### Install ncpol2sdpa from source Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/download.rst Commands to clone the development repository and install the package from the source code. ```bash $ git clone https://github.com/peterwittek/ncpol2sdpa.git $ cd ncpol2sdpa $ python setup.py install ``` -------------------------------- ### Install latest git version of ncpol2sdpa Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/README.rst Install the latest development version of ncpol2sdpa by cloning the repository and running setup.py. ```bash $ sudo python setup.py install ``` -------------------------------- ### Install ncpol2sdpa via pip Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/download.rst Standard installation command for the package using the Python Package Index. ```bash $ pip install ncpol2sdpa ``` -------------------------------- ### Initialize and Get SDP Relaxation Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Instantiate the `SdpRelaxation` object with the defined variables and call `get_relaxation` to generate the moment matrix. This step can be time-consuming. ```python sdp = SdpRelaxation(x) sdp.get_relaxation(level, objective=obj, inequalities=inequalities, substitutions=substitutions) ``` -------------------------------- ### Solve with PICOS Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Use P.solve() to solve the SDP relaxation and print P.value to get the result. ```python P.solve() print(P.value) ``` -------------------------------- ### Create and Solve SDP Relaxation Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Initializes an SdpRelaxation, gets a relaxation for a specified level, and solves it. Requires pre-defined operators and constraints. ```python level = 1 sdp = SdpRelaxation(P.get_all_operators(), normalized=False, verbose=1) sdp.get_relaxation(level, objective=-P([0],[0],'A'), momentequalities=behaviour_constraints, substitutions=P.substitutions) sdp.solve() print(sdp.primal, sdp.dual) ``` -------------------------------- ### Moroder Hierarchy for PPT Constraints Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Implements the Moroder hierarchy for quantum problems with Positive Partial Transpose (PPT) constraints. This example sets up the Probability class and I-matrix for a CHSH inequality. ```python from ncpol2sdpa import MoroderHierarchy, Probability, define_objective_with_I, flatten P = Probability([2, 2], [2, 2]) I = [[ 0, -1, 0], [-1, 1, 1], [ 0, 1, -1]] objective = define_objective_with_I(I, P) ``` -------------------------------- ### Configure SDP Relaxations Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Demonstrates various ways to configure relaxation levels, moment constraints, extra monomials, and chordal extensions. ```python momentequalities = ["-0[0,0]+1.0"] # String format for moment matrix entries sdp.get_relaxation(level=1, objective=objective, momentequalities=momentequalities) # Mixed-level relaxation with extra monomials from ncpol2sdpa import get_monomials extra = [X[0]*X[1]*X[0], X[1]*X[0]*X[1]] sdp.get_relaxation(level=1, objective=objective, extramonomials=extra) # Level -1: only use supplied monomials custom_monomials = [1, X[0], X[1], X[0]*X[1]] sdp.get_relaxation(level=-1, objective=objective, extramonomials=custom_monomials) # Enable chordal extension for sparse problems sdp.get_relaxation(level=2, objective=objective, chordal_extension=True) ``` -------------------------------- ### Solve SDP Relaxations Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Shows how to solve generated relaxations using different solvers and access primal/dual results. ```python from ncpol2sdpa import SdpRelaxation, generate_variables x = generate_variables('x', 2) sdp = SdpRelaxation(x) sdp.get_relaxation(level=2, objective=x[0]*x[1], inequalities=[-x[0]**2 + x[0], -x[1]**2 + x[1]]) # Auto-detect and use available solver sdp.solve() print(f"Primal: {sdp.primal}") # Optimal value (lower bound) print(f"Dual: {sdp.dual}") # Dual optimal value print(f"Status: {sdp.status}") # 'optimal', 'infeasible', etc. print(f"Time: {sdp.solution_time}") # Specify solver explicitly sdp.solve(solver='mosek') sdp.solve(solver='cvxopt') sdp.solve(solver='cvxpy') sdp.solve(solver='scs') # SDPA with custom executable and parameters sdp.solve(solver='sdpa', solverparameters={ 'executable': 'sdpa_gmp', # Arbitrary precision solver 'paramsfile': 'params.gmp.sdpa' }) # Access solution matrices x_mat = sdp.x_mat # Primal solution matrix y_mat = sdp.y_mat # Dual solution matrix ``` -------------------------------- ### Get Noncommutative Monomials Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Generates all noncommutative monomials up to a specified degree from a set of operators. Useful for custom relaxation levels. ```python from ncpol2sdpa import generate_operators, get_monomials X = generate_operators('X', 2, hermitian=True) # Get all monomials up to degree 2 monomials = get_monomials(X, 2) # Returns: [1, X0, X1, X0*X0, X0*X1, X1*X0, X1*X1, ...] # Degree 1 monomials only linear_monomials = get_monomials(X, 1) # Returns: [1, X0, X1] # Empty set for degree -1 empty = get_monomials(X, -1) # Returns: [] ``` -------------------------------- ### Manually Set Moment Matrix Elements and Solve with PICOS Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst After converting to a PICOS problem, manually define values for specific elements of the moment matrix and then solve the SDP using PICOS solvers. ```python X = P.get_variable('X') P.add_constraint(X[0, 1] == 0.5) ``` ```python P.solve() ``` -------------------------------- ### Create Moroder hierarchy with PPT constraint Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Demonstrates setting up a Moroder hierarchy with partial positivity constraints and converting the result to PICOS for additional constraints. ```python sdp = MoroderHierarchy( [flatten(P.parties[0]), flatten(P.parties[1])], verbose=1, normalized=False, ppt=True # Enable partial positivity constraint ) sdp.get_relaxation(level=1, objective=objective, substitutions=P.substitutions) sdp.solve() # For additional constraints, convert to PICOS P_picos = sdp.convert_to_picos(duplicate_moment_matrix=True) X = P_picos.get_variable('X') Y = P_picos.get_variable('Y') P_picos.add_constraint(Y.partial_transpose() >> 0) P_picos.solve() ``` -------------------------------- ### Initialize SdpRelaxation Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Creates the core SDP relaxation object. Manages moment matrix and constraint processing. Supports noncommutative operators, commutative variables, symbolic parameters, and verbosity settings. ```python from ncpol2sdpa import SdpRelaxation, generate_operators, generate_variables # Basic initialization with noncommutative operators X = generate_operators('X', 2, hermitian=True) sdp = SdpRelaxation(X) # With commutative variables x = generate_variables('x', 3) sdp = SdpRelaxation(x) # With verbosity for progress output sdp = SdpRelaxation(X, verbose=1) # With parallel processing enabled sdp = SdpRelaxation(X, parallel=True) # With symbolic parameters (not relaxed) from sympy import Symbol alpha = Symbol('alpha', real=True) sdp = SdpRelaxation(X, parameters=[alpha]) # Disable normalization (useful for post-processing) sdp = SdpRelaxation(X, normalized=False) ``` -------------------------------- ### Obtain and Solve SDP Relaxation Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/README.rst This snippet demonstrates how to define inequalities, substitutions, and obtain an SDP relaxation using the SdpRelaxation class. It then solves the relaxation and prints the primal, dual, and status. ```python inequalities = [-X[1] ** 2 + X[1] + 0.5 >= 0] # Simple monomial substitutions substitutions = {X[0]**2: X[0]} # Obtain SDP relaxation sdpRelaxation = SdpRelaxation(X) sdpRelaxation.get_relaxation(level, objective=obj, inequalities=inequalities, substitutions=substitutions) sdpRelaxation.solve() print(sdpRelaxation.primal, sdpRelaxation.dual, sdpRelaxation.status) ``` -------------------------------- ### Solve SDP with Specific Solver Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Configures and executes the solver. Use solverparameters for custom executables and parameter files. ```python sdp.solve(solver='sdpa', solverparameters={"executable":"sdpa_gmp", "paramsfile":"params.gmp.sdpa"}) ``` ```python sdp.solve(solver='cvxopt') print(sdp.primal, sdp.dual) ``` ```python sdp.solve(solver='mosek') print(sdp.primal, sdp.dual) ``` -------------------------------- ### Generate SDP Relaxation for a Bosonic System Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Set up and solve an SDP relaxation for a system of N harmonic oscillators, incorporating bosonic constraints. Requires `generate_operators` and `bosonic_constraints` helper functions. ```python from sympy.physics.quantum.dagger import Dagger level = 1 # Level of relaxation N = 4 # Number of variables hbar, omega = 1, 1 # Parameters for the Hamiltonian # Define ladder operators a = generate_operators('a', N) hamiltonian = sum(hbar*omega*(Dagger(ai)*ai+0.5) for ai in a) substitutions = bosonic_constraints(a) sdp = SdpRelaxation(a) sdp.get_relaxation(level, objective=hamiltonian, substitutions=substitutions) sdp.solve() ``` -------------------------------- ### Initialize Moroder Hierarchy with PPT Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Initializes a MoroderHierarchy object with the 'ppt=True' argument, which enforces partial positivity of the moment matrix, leading to a sparser SDP. ```python sdp = MoroderHierarchy([flatten(P.parties[0]), flatten(P.parties[1])], verbose=1, ppt=True) sdp.get_relaxation(level, objective=objective, substitutions=P.substitutions) ``` -------------------------------- ### Initialize Probability Distribution for Joint Probabilities Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Initialize a `Probability` object to handle joint probability distributions, specifying the number of outcomes for each party. Used in conjunction with QuTiP for quantum state manipulation. ```python from math import sqrt from qutip import tensor, basis, sigmax, sigmay, expect, qeye P = Probability([2, 2], [2, 2]) ``` -------------------------------- ### SdpRelaxation.solve Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Solves the generated SDP relaxation using specified solvers and stores the results. ```APIDOC ## POST /SdpRelaxation/solve ### Description Executes the solver on the generated SDP relaxation and populates the primal and dual solution attributes. ### Parameters #### Request Body - **solver** (string) - Optional - The solver to use (e.g., 'mosek', 'cvxopt', 'cvxpy', 'scs', 'sdpa'). - **solverparameters** (dict) - Optional - Configuration parameters for the chosen solver. ``` -------------------------------- ### Convert to PICOS Problem Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Converts the SDP relaxation to a PICOS problem, allowing for further manipulation and constraint addition. 'duplicate_moment_matrix=True' creates a copy of the moment matrix. ```python Problem = sdp.convert_to_picos(duplicate_moment_matrix=True) X = Problem.get_variable('X') Y = Problem.get_variable('Y') Z = Problem.add_variable('Z', (sdp.block_struct[0], sdp.block_struct[0])) Problem.add_constraint(Y.partial_transpose()>>0) Problem.add_constraint(Z.partial_transpose()>>0) Problem.add_constraint(X - Y + Z == 0) Problem.add_constraint(Z[0,0] == 1) solution = Problem.solve() print(solution) ``` -------------------------------- ### Convert SDP to PICOS Problem Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Convert an existing SDP relaxation problem into a PICOS optimization problem for further manipulation or to use PICOS solvers. ```python P = sdp.convert_to_picos() ``` -------------------------------- ### Implement SteeringHierarchy Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Implements the hierarchy for quantum steering scenarios with matrix-valued SDP variables. ```python from ncpol2sdpa import SteeringHierarchy, generate_operators # Alice's measurements (trusted) A = generate_operators('A', 2, hermitian=True) # Create steering hierarchy with matrix variable dimension sdp = SteeringHierarchy(A, verbose=1, matrix_var_dim=2) # Define steering objective (typically involves matrix traces) from sympy import zeros, Symbol objective = zeros(2, 2) objective[0, 0] = A[0] objective[1, 1] = A[1] sdp.get_relaxation(level=1, objective=objective) sdp.solve() ``` -------------------------------- ### SdpRelaxation.write_to_file Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Exports the SDP relaxation to various file formats. ```APIDOC ## POST /SdpRelaxation/write_to_file ### Description Writes the current SDP relaxation to a file in a specified format. ### Parameters #### Request Body - **filename** (string) - Required - The path and name of the file to export (e.g., .dat-s, .task, .csv). ``` -------------------------------- ### Calculate and Apply Behaviour Constraints Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Calculate the expected value of a projector for a given quantum state and measurement, and use it to define a behaviour constraint for the probability distribution. ```python behaviour_constraints = [ P([0],[0],'A')-expect(tensor(A[0], qeye(2)), psi), ``` -------------------------------- ### Generate SDP Relaxation Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Generates the SDP relaxation with specified level, objective function, and constraints. Supports inequality, equality, and substitution constraints. ```python from ncpol2sdpa import SdpRelaxation, generate_operators # Setup problem X = generate_operators('X', 2, hermitian=True) sdp = SdpRelaxation(X) # Basic relaxation at level 2 objective = X[0] * X[1] + X[1] * X[0] inequalities = [-X[1]**2 + X[1] + 0.5] # Assumed >= 0 substitutions = {X[0]**2: X[0]} # Idempotent: X0^2 = X0 sdp.get_relaxation( level=2, objective=objective, inequalities=inequalities, substitutions=substitutions ) # With equality constraints (converted to pairs of inequalities) equalities = [X[0] + X[1] - 1] sdp.get_relaxation(level=2, objective=objective, equalities=equalities) # Remove equalities via linear algebra (faster, sparser) sdp.get_relaxation(level=2, objective=objective, equalities=equalities, removeequalities=True) ``` -------------------------------- ### Perform Sparse Relaxation with Chordal Extension Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Replicates SparsePOP behavior by applying chordal extension to the SDP relaxation. ```python level = 2 X = generate_variables('x', 3) obj = X[1] - 2*X[0]*X[1] + X[1]*X[2] inequalities = [1-X[0]**2-X[1]**2, 1-X[1]**2-X[2]**2] sdp = SdpRelaxation(X) sdp.get_relaxation(level, objective=obj, inequalities=inequalities, chordal_extension=True) sdp.solve() print(sdp.primal, sdp.dual) ``` -------------------------------- ### Generate Pauli Constraints Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Generates substitution rules for Pauli spin operators on multiple sites. Use this for Heisenberg Hamiltonians. ```python from ncpol2sdpa import generate_operators, pauli_constraints, SdpRelaxation # Create Pauli operators for N sites N = 3 X = generate_operators('X', N, hermitian=True) Y = generate_operators('Y', N, hermitian=True) Z = generate_operators('Z', N, hermitian=True) # Get Pauli algebra substitutions substitutions = pauli_constraints(X, Y, Z) # Includes: X^2 = Y^2 = Z^2 = 1, anticommutation on same site, # commutation between different sites # Define Heisenberg Hamiltonian J = 1.0 hamiltonian = sum(J*(X[i]*X[i+1] + Y[i]*Y[i+1] + Z[i]*Z[i+1]) for i in range(N-1)) sdp = SdpRelaxation(X + Y + Z) sdp.get_relaxation(level=1, objective=hamiltonian, substitutions=substitutions) sdp.solve() print(f"Ground state energy: {sdp.primal}") ``` -------------------------------- ### Write SDP Relaxation to File Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Writes the current SDP relaxation to a file in a format compatible with SeDuMi. Useful for post-processing in other environments like MATLAB. ```python sdp.write_to_file("chsh-moroder.dat-s") ``` -------------------------------- ### SdpRelaxation Class Methods Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/reference.rst Methods available for the SdpRelaxation class, used for semidefinite programming relaxations. ```APIDOC ## SdpRelaxation Class Methods ### Description Provides methods for setting up, processing, and solving semidefinite programming relaxations. ### Methods - `get_relaxation()` - `set_objective()` - `process_constraints()` - `solve()` - `__getitem__()` - `write_to_file()` - `save_monomial_index()` - `get_sos_decomposition()` - `find_solution_ranks()` - `convert_to_picos()` - `convert_to_mosek()` - `extract_dual_value()` ``` -------------------------------- ### Export SDP Relaxation to File Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Exports the current relaxation to an SDPA format file. ```python sdp.write_to_file('example.dat-s') ``` -------------------------------- ### SteeringHierarchy Class Methods Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/reference.rst Methods available for the SteeringHierarchy class, another hierarchy for polynomial optimization. ```APIDOC ## SteeringHierarchy Class Methods ### Description Provides methods for setting up, processing, and solving polynomial optimization problems using a steering hierarchy approach. ### Methods - `get_relaxation()` - `set_objective()` - `process_constraints()` - `solve()` - `__getitem__()` - `write_to_file()` - `save_monomial_index()` - `convert_to_picos()` - `convert_to_mosek()` ``` -------------------------------- ### Find Solution Ranks Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Checks for rank loops to determine convergence. ```python sdp.solve(solver='sdpa', solverparameters={"executable":"sdpa_gmp", "paramsfile"="params.gmp.sdpa"}) sdp.find_solution_ranks() ``` -------------------------------- ### Solve Max-cut Problem Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Demonstrates solving a commutative polynomial optimization problem by removing equality constraints using NumPy. ```python import numpy as np W = np.diag(np.ones(8), 1) + np.diag(np.ones(7), 2) + np.diag([1, 1], 7) + \ np.diag([1], 8) W = W + W.T n = len(W) e = np.ones(n) Q = (np.diag(np.dot(e.T, W)) - W) / 4 x = generate_variables('x', n) equalities = [xi ** 2 - 1 for xi in x] objective = -np.dot(x, np.dot(Q, np.transpose(x))) sdp = SdpRelaxation(x) sdp.get_relaxation(1, objective=objective, equalities=equalities, removeequalities=True) sdp.solve() ``` -------------------------------- ### Solve Parametric Polynomial Optimization Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Approximates a parametric function using dual SDP relaxation based on Lasserre (2010). ```python from math import sqrt from sympy import integrate, N import matplotlib.pyplot as plt def J(x): return -2*abs(1-2*x)*sqrt(x/(1+x)) def Jk(x, coeffs): return sum(ci*x**i for i, ci in enumerate(coeffs)) level = 4 x = generate_variables('x')[0] y = generate_variables('y', 2) f = (1-2*x)*(y[0] + y[1]) gamma = [integrate(x**i, (x, 0, 1)) for i in range(1, 2*level+1)] marginals = flatten([[x**i-N(gamma[i-1]), N(gamma[i-1])-x**i] for i in range(1, 2*level+1)]) inequalities = [x*y[0]**2 + y[1]**2 - x, - x*y[0]**2 - y[1]**2 + x, y[0]**2 + x*y[1]**2 - x, - y[0]**2 - x*y[1]**2 + x, 1-x, x] sdp = SdpRelaxation(flatten([x, y])) sdp.get_relaxation(level, objective=f, momentinequalities=marginals, inequalities=inequalities) sdp.solve() coeffs = [sdp.extract_dual_value(0, range(len(inequalities)+1))] coeffs += [sdp.y_mat[len(inequalities)+1+2*i][0][0] - sdp.y_mat[len(inequalities)+1+2*i+1][0][0] for i in range(len(marginals)//2)] x_domain = [i/100. for i in range(100)] plt.plot(x_domain, [J(xi) for xi in x_domain], linewidth=2.5) plt.plot(x_domain, [Jk(xi, coeffs) for xi in x_domain], linewidth=2.5) plt.show() ``` -------------------------------- ### Convert to PICOS Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Converts the relaxation into a PICOS problem object for advanced constraint manipulation. ```python from ncpol2sdpa import SdpRelaxation, generate_operators X = generate_operators('X', 2, hermitian=True) sdp = SdpRelaxation(X) sdp.get_relaxation(level=1, objective=X[0]*X[1]+X[1]*X[0]) # Convert to PICOS for additional manipulations P = sdp.convert_to_picos() # Access and modify the moment matrix moment_matrix = P.get_variable('X') P.add_constraint(moment_matrix[0, 1] == 0.5) P.add_constraint(moment_matrix[1, 1] >= 0.3) ``` -------------------------------- ### SdpRelaxation Class Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Manages the SDP relaxation process, including constraint processing and generating relaxations. ```APIDOC ## SdpRelaxation Constructor ### Description Creates the core SDP relaxation object that manages the moment matrix and constraint processing. ### Method `SdpRelaxation(variables, verbose=0, parallel=False, parameters=None, normalized=True)` ### Parameters #### Path Parameters None #### Query Parameters - **variables** (list) - Required - A list of SymPy symbols or noncommutative operators. - **verbose** (int) - Optional - Controls the verbosity of the output. Defaults to 0. - **parallel** (bool) - Optional - Enables parallel processing. Defaults to False. - **parameters** (list) - Optional - A list of symbolic parameters that are not relaxed. - **normalized** (bool) - Optional - Whether to normalize the problem. Defaults to True. ### Request Example ```python from ncpol2sdpa import SdpRelaxation, generate_operators, generate_variables # Basic initialization with noncommutative operators X = generate_operators('X', 2, hermitian=True) sdp = SdpRelaxation(X) # With commutative variables x = generate_variables('x', 3) sdp = SdpRelaxation(x) # With verbosity for progress output sdp = SdpRelaxation(X, verbose=1) # With parallel processing enabled sdp = SdpRelaxation(X, parallel=True) # With symbolic parameters (not relaxed) from sympy import Symbol alpha = Symbol('alpha', real=True) sdp = SdpRelaxation(X, parameters=[alpha]) # Disable normalization (useful for post-processing) sdp = SdpRelaxation(X, normalized=False) ``` ## SdpRelaxation.get_relaxation ### Description Generates the SDP relaxation with specified level, objective function, and constraints. ### Method `get_relaxation(level, objective, inequalities=None, equalities=None, substitutions=None, removeequalities=False)` ### Parameters #### Path Parameters None #### Query Parameters - **level** (int) - Required - The relaxation level. - **objective** (SymPy expression) - Required - The objective function to minimize or maximize. - **inequalities** (list) - Optional - A list of inequality constraints (assumed to be >= 0). - **equalities** (list) - Optional - A list of equality constraints. - **substitutions** (dict) - Optional - A dictionary of substitutions to apply. - **removeequalities** (bool) - Optional - If True, equalities are removed via linear algebra, potentially leading to faster and sparser problems. Defaults to False. ### Request Example ```python from ncpol2sdpa import SdpRelaxation, generate_operators # Setup problem X = generate_operators('X', 2, hermitian=True) sdp = SdpRelaxation(X) # Basic relaxation at level 2 objective = X[0] * X[1] + X[1] * X[0] inequalities = [-X[1]**2 + X[1] + 0.5] # Represents >= 0 substitutions = {X[0]**2: X[0]} # Idempotent: X0^2 = X0 sdp.get_relaxation( level=2, objective=objective, inequalities=inequalities, substitutions=substitutions ) # With equality constraints (converted to pairs of inequalities) equalities = [X[0] + X[1] - 1] sdp.get_relaxation(level=2, objective=objective, equalities=equalities) # Remove equalities via linear algebra (faster, sparser) sdp.get_relaxation(level=2, objective=objective, equalities=equalities, removeequalities=True) ``` ``` -------------------------------- ### Implement RdmHierarchy Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Implements the reduced density matrix (RDM) method for ground-state problems with translational invariance. ```python from ncpol2sdpa import RdmHierarchy, generate_operators, fermionic_constraints from sympy.physics.quantum.dagger import Dagger # Fermionic system with translational invariance N = 6 c = generate_operators('c', N, hermitian=False) substitutions = fermionic_constraints(c) # Create RDM hierarchy with circulant structure sdp = RdmHierarchy(c, verbose=1, circulant=True) # Define translationally invariant Hamiltonian t = 1.0 hamiltonian = sum(-t*(Dagger(c[i])*c[(i+1)%N] + Dagger(c[(i+1)%N])*c[i]) for i in range(N)) sdp.get_relaxation(level=1, objective=hamiltonian, substitutions=substitutions) sdp.solve() print(f"Ground state energy per site: {sdp.primal/N}") ``` -------------------------------- ### Define a polynomial optimization problem Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/README.rst Initialize operators and define an objective function for a semidefinite programming relaxation. ```python from ncpol2sdpa import generate_operators, SdpRelaxation # Number of operators n_vars = 2 # Level of relaxation level = 2 # Get Hermitian operators X = generate_operators('X', n_vars, hermitian=True) # Define the objective function obj = X[0] * X[1] + X[1] * X[0] # Inequality constraints ``` -------------------------------- ### SdpRelaxation.get_relaxation Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Generates an SDP relaxation for a given objective and set of constraints. ```APIDOC ## POST /SdpRelaxation/get_relaxation ### Description Generates the SDP relaxation based on the specified hierarchy level, objective function, and optional constraints. ### Parameters #### Request Body - **level** (int) - Required - The relaxation level (e.g., 1, 2, -1). - **objective** (expression) - Required - The polynomial objective function. - **momentequalities** (list) - Optional - String format for moment matrix entries. - **extramonomials** (list) - Optional - Additional monomials to include in the relaxation. - **chordal_extension** (bool) - Optional - Enable chordal extension for sparse problems. ``` -------------------------------- ### Solve the SDP Relaxation Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Solve the generated SDP relaxation using available solvers (SDPA, MOSEK, CVXOPT). The solution, dual variables, and status are stored in the `sdp` object. ```python sdp.solve() print(sdp.primal, sdp.dual, sdp.status) ``` -------------------------------- ### Export SDP Relaxations Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Exports the relaxation to various file formats including SDPA, MOSEK, and CSV. ```python from ncpol2sdpa import SdpRelaxation, generate_variables x = generate_variables('x', 2) sdp = SdpRelaxation(x) sdp.get_relaxation(level=2, objective=x[0]*x[1], inequalities=[1-x[0]**2, 1-x[1]**2]) # Export to sparse SDPA format (for SDPA, CSDP, MATLAB) sdp.write_to_file('problem.dat-s') # Export to MOSEK task format sdp.write_to_file('problem.task') # Export to human-readable CSV format sdp.write_to_file('problem.csv') # Save monomial index for debugging sdp.save_monomial_index('monomials.txt') ``` -------------------------------- ### Define Objective and Generate Monomials for SDP Relaxation Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Flip the sign of the objective function for minimization and generate extra monomials for the SDP relaxation. Requires `SdpRelaxation` and `Probability` classes. ```python objective = -CHSH ``` ```python sdp = SdpRelaxation(P.get_all_operators()) sdp.get_relaxation(level, objective=objective, substitutions=P.substitutions, extramonomials=P.get_extra_monomials('AB')) sdp.solve() print(sdp.primal) ``` -------------------------------- ### MoroderHierarchy Class Methods Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/reference.rst Methods available for the MoroderHierarchy class, a type of hierarchy for polynomial optimization. ```APIDOC ## MoroderHierarchy Class Methods ### Description Provides methods for setting up, processing, and solving polynomial optimization problems using a hierarchy approach. ### Methods - `get_relaxation()` - `set_objective()` - `process_constraints()` - `solve()` - `__getitem__()` - `write_to_file()` - `save_monomial_index()` - `convert_to_picos()` - `convert_to_mosek()` ``` -------------------------------- ### Define Equality Constraint as Substitution Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Represent equality constraints as substitution rules to potentially create sparser SDP relaxations. This is an alternative to converting equalities into two inequalities. ```python substitutions = {x[0]**2 : x[0]} ``` -------------------------------- ### Debug SDP Relaxation Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/tutorial.rst Exports the relaxation to a CSV file or saves the mapping between SDP variables and monomials. ```python sdp.write_to_file("examples.csv") ``` ```python sdp.save_monomial_index("monomials.txt") ``` -------------------------------- ### Solver Output Study Functions Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/reference.rst Functions for reading and analyzing the output of solvers. ```APIDOC ## Solver Output Study Functions ### Description Function to read and parse output files from SDPA solvers. ### Functions - `read_sdpa_out()` ``` -------------------------------- ### Generate Commutative Variables Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Creates lists of real or complex symbolic variables for polynomial optimization. Use to define polynomials with commutative algebras. ```python from ncpol2sdpa import generate_variables # Generate 3 real commutative variables x = generate_variables('x', 3) # Returns: [x0, x1, x2] as real SymPy Symbols # Generate a single variable y = generate_variables('y')[0] # Generate complex commutative variables z = generate_variables('z', 2, hermitian=False) # Use variables to define polynomials objective = x[0]*x[1] + x[1]*x[2] - 2*x[0]**2 inequality = 1 - x[0]**2 - x[1]**2 # Represents >= 0 ``` -------------------------------- ### Detect Solution Ranks Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Checks for rank loops in the solution matrix to verify if the relaxation has converged to an exact optimum. ```python from ncpol2sdpa import SdpRelaxation, generate_operators X = generate_operators('X', 2, hermitian=True) sdp = SdpRelaxation(X) sdp.get_relaxation(level=2, objective=X[0]*X[1]+X[1]*X[0], substitutions={X[0]**2: X[0]}) sdp.solve(solver='sdpa', solverparameters={'executable': 'sdpa_gmp'}) # Check for rank loop (indicates exact solution found) ranks = sdp.find_solution_ranks() print(f"Solution ranks: {ranks}") # If ranks show pattern like [2, 2], a rank loop exists # Rank loop means the relaxation has converged to exact optimum ``` -------------------------------- ### Generate Noncommutative Operators Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Creates lists of Hermitian or non-Hermitian operators for quantum optimization and NPA hierarchy relaxations. Order matters in noncommutative polynomials. ```python from ncpol2sdpa import generate_operators from sympy.physics.quantum.dagger import Dagger # Generate 2 Hermitian noncommutative operators X = generate_operators('X', 2, hermitian=True) # Returns: [X0, X1] as HermitianOperator objects # Generate non-Hermitian ladder operators for bosonic/fermionic systems a = generate_operators('a', 4, hermitian=False) # a[i] and Dagger(a[i]) are distinct # Define a noncommutative polynomial (order matters!) obj = X[0] * X[1] + X[1] * X[0] # Different from 2*X[0]*X[1] # Hermitian operators satisfy: Dagger(X[i]) == X[i] # Non-Hermitian: Dagger(a[i]) != a[i] ``` -------------------------------- ### Solve Commutative Polynomial Optimization (Max-Cut) Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Solves a Max-Cut problem using SdpRelaxation with equality removal for variables constrained to x_i^2 = 1. ```python import numpy as np from ncpol2sdpa import generate_variables, SdpRelaxation # Max-cut problem on a graph W = np.diag(np.ones(8), 1) + np.diag(np.ones(7), 2) + \ np.diag([1, 1], 7) + np.diag([1], 8) W = W + W.T n = len(W) e = np.ones(n) Q = (np.diag(np.dot(e.T, W)) - W) / 4 # Variables with x_i^2 = 1 constraint x = generate_variables('x', n) equalities = [xi**2 - 1 for xi in x] # Objective: maximize x'Qx (minimize negative) objective = -np.dot(x, np.dot(Q, np.transpose(x))) # Solve with equality removal sdp = SdpRelaxation(x) sdp.get_relaxation(1, objective=objective, equalities=equalities, removeequalities=True) sdp.solve() print(f"Max-cut bound: {-sdp.primal}") ``` -------------------------------- ### Define Expectation Values Source: https://github.com/peterwittek/ncpol2sdpa/blob/master/doc/source/examples.rst Defines expectation values for different operators and states. Used for setting up SDP constraints. ```python P([0],[1],'A')-expect(tensor(A[1], qeye(2)), psi), P([0],[0],'B')-expect(tensor(qeye(2), B[0]), psi), P([0],[1],'B')-expect(tensor(qeye(2), B[1]), psi), P([0,0],[0,0])-expect(tensor(A[0], B[0]), psi), P([0,0],[0,1])-expect(tensor(A[0], B[1]), psi), P([0,0],[1,0])-expect(tensor(A[1], B[0]), psi), P([0,0],[1,1])-expect(tensor(A[1], B[1]), psi)] ``` -------------------------------- ### Generate Bosonic Constraints Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Generates substitution rules for bosonic ladder operators satisfying canonical commutation relations. Use this for Hamiltonians involving harmonic oscillators. ```python from ncpol2sdpa import generate_operators, bosonic_constraints, SdpRelaxation from sympy.physics.quantum.dagger import Dagger # Create bosonic ladder operators N = 4 a = generate_operators('a', N, hermitian=False) # Get substitutions: [a_i, a_j†] = delta_ij, [a_i, a_j] = 0 substitutions = bosonic_constraints(a) # Includes: a*Dagger(a) -> 1 + Dagger(a)*a, and commutation relations # Define bosonic Hamiltonian (harmonic oscillators) hbar, omega = 1, 1 hamiltonian = sum(hbar*omega*(Dagger(ai)*ai + 0.5) for ai in a) # Solve for ground state energy sdp = SdpRelaxation(a) sdp.get_relaxation(level=1, objective=hamiltonian, substitutions=substitutions) sdp.solve() print(f"Ground state energy: {sdp.primal}") # Should be N*hbar*omega/2 = 2 ``` -------------------------------- ### Generate Fermionic Constraints Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Generates substitution rules for fermionic ladder operators satisfying canonical anticommutation relations. Use this for Hamiltonians involving tight-binding models. ```python from ncpol2sdpa import generate_operators, fermionic_constraints, SdpRelaxation from sympy.physics.quantum.dagger import Dagger # Create fermionic ladder operators N = 3 c = generate_operators('c', N, hermitian=False) # Get substitutions: {c_i, c_j†} = delta_ij, {c_i, c_j} = 0 substitutions = fermionic_constraints(c) # Includes: c**2 -> 0, c*Dagger(c) -> 1 - Dagger(c)*c, anticommutation # Define fermionic Hamiltonian (e.g., tight-binding) t = 1.0 # Hopping parameter hamiltonian = sum(-t*(Dagger(c[i])*c[i+1] + Dagger(c[i+1])*c[i]) for i in range(N-1)) sdp = SdpRelaxation(c) sdp.get_relaxation(level=1, objective=hamiltonian, substitutions=substitutions) sdp.solve() print(f"Ground state energy: {sdp.primal}") ``` -------------------------------- ### Probability Class for Bell Inequalities Source: https://context7.com/peterwittek/ncpol2sdpa/llms.txt Provides an interface for quantum probabilities and Bell inequalities, such as CHSH. Configure with party measurement and outcome counts. ```python from ncpol2sdpa import Probability, SdpRelaxation, define_objective_with_I, flatten # CHSH scenario: 2 parties, 2 measurements each, 2 outcomes each # Configuration: list of outputs per measurement P = Probability([2, 2], [2, 2]) # Alice: 2 meas, Bob: 2 meas # Access probabilities p(ab|xy) p_00_00 = P([0, 0], [0, 0]) # p(a=0,b=0|x=0,y=0) p_11_01 = P([1, 1], [0, 1]) # p(a=1,b=1|x=0,y=1) # Marginal probabilities p_A_0_0 = P([0], [0], 'A') # p_A(a=0|x=0) p_B_1_1 = P([1], [1], 'B') # p_B(b=1|y=1) # Define CHSH Bell inequality CHSH = -P([0],[0],'A') + P([0,0],[0,0]) + P([0,0],[0,1]) + \ P([0,0],[1,0]) - P([0,0],[1,1]) - P([0],[0],'B') # Or use I-matrix notation (Collins-Gisin) I = [[ 0, -1, 0], [-1, 1, 1], [ 0, 1, -1]] objective = define_objective_with_I(I, P) # Solve for maximum quantum violation sdp = SdpRelaxation(P.get_all_operators()) sdp.get_relaxation(level=1, objective=-CHSH, substitutions=P.substitutions, extramonomials=P.get_extra_monomials('AB')) sdp.solve() print(f"Max CHSH violation: {-sdp.primal}") # ~2.828 (Tsirelson bound) ```