kaiwu.core package#
Module contents#
Module: core
Function: Definition of Baseses
- class kaiwu.core.IsingSolver[source]#
Bases:
objectBases for Ising solvers
- on_matrix_change()[source]#
Update matrix-related information; can be implemented when inheriting from IsingSolver. When the Ising matrix being processed changes, the implementation of this function will be called to allow corresponding actions.
- class kaiwu.core.QuboSolver[source]#
Bases:
objectBases for Solvers
- Args:
optimizer (IsingSolver): Ising solver
- kaiwu.core.get_sorted_solutions(matrix, solutions, bias=0.0, negtail_ff=True, sort_solutions=True)[source]#
Optimal solution sampling.
- Args:
matrix (np.ndarray): Ising matrix.
solutions (np.ndarray): variable configurations.
bias (float): constant term.
negtail_ff (bool): negtail_flip flag for negative-tail flipping; matrices produced by quadratizing linear terms in an Ising model require negative-tail flipping.
- Returns:
output (np.ndarray, np.ndarray): variable configurations sorted by energy, and energy values.
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> matrix = -np.array([[ 0. , 1. , 0. , 1. , 1. ], ... [ 1. , 0. , 0. , 1., 1. ], ... [ 0. , 0. , 0. , 1., 1. ], ... [ 1. , 1., 1. , 0. , 1. ], ... [ 1. , 1., 1. , 1. , 0. ]]) >>> solutions = np.array([[ 1, -1, 1, -1, -1], ... [-1, -1, 1, -1, -1], ... [-1, -1, -1, 1, 1], ... [ 1, 1, 1, -1, -1], ... [ 1, 1, 1, -1, -1], ... [ 1, 1, 1, -1, -1]]) >>> kw.core.get_sorted_solutions(matrix, solutions, 0) (array([[-1, -1, -1, 1, 1], [-1, -1, -1, 1, 1], [-1, -1, -1, 1, 1], [-1, -1, -1, 1, 1], [-1, 1, -1, 1, 1], [ 1, 1, -1, 1, 1]]), array([-8., -8., -8., -8., -4., 8.]))
- exception kaiwu.core.KaiwuError[source]#
Bases:
ExceptionBases for exceptions in this module.
- args#
- with_traceback()#
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- kaiwu.core.get_min_penalty(obj, cons)[source]#
Return the minimum penalty coefficient corresponding to the constraint term ‘cons’, with the penalty term taking priority.
- Args:
obj: QUBO expression of the original objective function.
cons: QUBO expression of the constraint term
- Returns:
float: Minimum penalty coefficient corresponding to the constraint term ‘cons’.
- Examples:
>>> import kaiwu as kw >>> x = [kw.core.Binary(f"b{i}") for i in range(3)] >>> cons = kw.core.quicksum(x) - 1 >>> obj = x[1] + 2 * x[2] >>> kw.core.get_min_penalty(obj, cons) 2.0
- kaiwu.core.get_min_penalty_from_min_diff(cons, negative_delta, positive_delta)[source]#
Estimate the minimum penalty coefficient of the constraint term based on the maximum and minimum values of the objective.
- Args:
cons: Constraint term
negative_delta: Minimum value of the objective
positive_delta: Maximum value of the objective
- Returns:
Found minimum penalty coefficient
- kaiwu.core.get_min_penalty_for_equal_constraint(obj, cons)[source]#
Return the minimum penalty coefficient corresponding to the linear equality constraint term ‘cons’: the worst-case scenario when flipping one bit of the solution that satisfies this constraint. This penalty coefficient is valid in the sense that it ensures the feasible solution of the original problem is a local optimum of the objective function (in the local sense of one-bit flip).
- Args:
obj: QUBO expression of the original objective function.
cons: Linear expression in the linear equality constraint cons=0.
- Returns:
float: Minimum penalty coefficient corresponding to the linear equality constraint term ‘cons’.
- Examples:
>>> import kaiwu as kw >>> x = [kw.core.Binary(f"b{i}") for i in range(3)] >>> cons = kw.core.quicksum(x)-1 >>> obj = x[1]+2*x[2] >>> kw.core.get_min_penalty_for_equal_constraint(obj,cons) 2.0
- kaiwu.core.get_min_penalty_from_deltas(cons, neg_delta, pos_delta, obj_vars, min_delta_method='diff')[source]#
Return the minimum penalty coefficient corresponding to the constraint term ‘cons’, with the penalty term taking priority.
- Args:
cons: QUBO expression of the constraint term
neg_delta: Dictionary of maximum changes when each variable is flipped from 1 to 0
pos_delta: Dictionary of maximum changes when each variable is flipped from 0 to 1
obj_vars: The third element is a list of variables
- min_delta_method: Declared in. Two methods are used to find the minimum change value respectively
MIN_DELTA_METHODS = {“diff”: _get_constraint_min_deltas_diff, “exhaust”: _get_constraint_min_deltas_exhaust}
- Examples:
>>> import kaiwu as kw >>> x = [kw.core.Binary(f"b{i}") for i in range(3)] >>> cons = kw.core.quicksum(x) - 1 >>> obj = x[1]+2*x[2] >>> kw.core.get_min_penalty(obj, cons) 2.0
- class kaiwu.core.PenaltyMethodConstraint(expr, penalty=1, parent_model=None)[source]#
Bases:
objectPenalty method for converting constrained problems to unconstrained problems
- Args:
expr (Expression): Compiled constraint term expression
penalty (float): Penalty coefficient of the constraint term
- classmethod from_constraint_definition(name, constraint: Constraint, parent_model)[source]#
Prepare QUBO expression for the given constraint, automatically determining slack variables if needed.
- Args:
name: Name of the constraint.
constraint: The relation constraint to process.
parent_model: the model it belongs to.
- kaiwu.core.get_sol_dict(solution, vars_dict)[source]#
Generate result dictionary based on solution vector and variable dictionary.
- Args:
solution (np.ndarray): Solution vector (spin).
vars_dict (dict): Variable dictionary, generated by cim_ising_model.get_variables().
- Returns:
dict: Result dictionary. Keys are variable names, values are corresponding spin values.
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> d = kw.core.QuboModel(d) >>> d_ising = kw.core.qubo_model_to_ising_model(d) >>> vars = d_ising.get_variables() >>> s = np.array([1, -1, 1]) >>> kw.core.get_sol_dict(s, vars) {'a': np.float64(1.0), 'b': np.float64(0.0), 'c': np.float64(1.0)}
- kaiwu.core.get_val(qubo, sol_dict)[source]#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (BinaryExpression or BinaryExpressionNDArray): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> qubo_model = kw.core.QuboModel(d) >>> d_ising = kw.core.qubo_model_to_ising_model(qubo_model) >>> ising_vars = d_ising.get_variables() >>> s = np.array([1, -1, 1]) >>> sol_dict = kw.core.get_sol_dict(s, ising_vars) >>> kw.core.get_val(d, sol_dict) np.float64(5.0)
- class kaiwu.core.Expression(coefficient: dict | None = None, offset: float = 0)[source]#
Bases:
objectUniversal Bases for QUBO/Ising expressions (provides default quadratic expression implementation)
- get_max_deltas()[source]#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)[source]#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- class kaiwu.core.BinaryModel(objective=None)[source]#
Bases:
objectBinary model class
- Args:
objective (BinaryExpression, optional): Objective function. Defaults to None
- set_constraint_handler(constraint_handler)[source]#
Set the unconstrained conversion method for constraint terms
- Args:
constraint_handler: Class for setting the unconstrained representation method of constraint terms
- set_objective(objective)[source]#
Set the objective function
- Args:
objective (BinaryExpression): Objective function expression
- add_constraint(constraint_in, name=None, constr_type: Literal['soft', 'hard'] = 'hard', penalty=1, slack_var_expr=None)[source]#
Add constraint terms; single or multiple constraints are supported
- Args:
constraint_in: constraint expression; two input types are supported:
Single constraint: BinaryExpression Constraint for example:
quicksum(x) - 1Constraint(quicksum(x) - 1, "==", 1)Multiple constraints: list/tuple/np.ndarray, automatically iterated and added one by one for example:
[constraint1, constraint2, constraint3]
- name (str or list, optional): constraint name, automatically named by default. when multiple constraints are provided,
If a string is passed, it is used as a common prefix; if a list of strings is passed, it must match the number of constraints.
penalty (float, optional): default penalty coefficient
constr_type(str, optional): Constraint type, can be set to “soft” or “hard”, defaults to “hard”
- slack_var_expr (BinaryExpression, optional): slack variable expression, used only in inequality constraints,
generated automatically by default
- Example1 (Single BinaryExpression):
>>> import kaiwu as kw >>> model = kw.core.QuboModel() >>> x = [kw.core.Binary(f"x{i}") for i in range(3)] >>> model.add_constraint(kw.core.quicksum(x) - 1)
- Example2 (Constraint with relation operator):
>>> from kaiwu.core._constraint import Constraint >>> model.add_constraint(Constraint(kw.core.quicksum(x) - 1, "==", 1))
- Examples3 (Multiple Constraints):
>>> constraints = [x[i] - 1 for i in range(3)] >>> model.add_constraint(constraints, name="my_constraints")
- get_value(solution_dict)[source]#
Substitute variable values into QUBO variables based on the result dictionary.
- Args:
solution_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- verify_constraint(solution_dict, constr_type: Literal['soft', 'hard'] = 'hard')[source]#
Verify whether constraints are satisfied
- Args:
solution_dict (dict): QUBO model solution dictionary
constr_type(str, optional): Constraint type, can be set to “soft” or “hard”, defaults to “hard”
- Returns:
- tuple: Constraint satisfaction information
int: Number of unsatisfied constraints
dict: Dictionary containing constraint values
- class kaiwu.core.BinaryExpression(coefficient: dict | None = None, offset: float = 0)[source]#
Bases:
ExpressionBasic data structure for QUBO expressions
- feed(feed_dict)[source]#
Assign values to placeholders and return a new expression object after assignment
- Args:
feed_dict(dict): Values for placeholders to be assigned
- Examples:
>>> import kaiwu as kw >>> p = kw.core.Placeholder('p') >>> a = kw.core.Binary('a') >>> y = p * a >>> str(y) '(p)*a' >>> y= y.feed({'p': 2}) >>> str(y) '2*a'
- clear() None#
Set the expression to 0
- get_average_coefficient()#
Return the average value of coefficients
- get_max_deltas()#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- get_variables()#
Get the set of variable names
- Returns:
dict: returnexpressionvariable
- class kaiwu.core.Binary(name: str = '')[source]#
Bases:
BinaryExpressionBinary variable: only stores the variable name, does not inherit QuboExpression
- feed(feed_dict)#
Assign values to placeholders and return a new expression object after assignment
- Args:
feed_dict(dict): Values for placeholders to be assigned
- Examples:
>>> import kaiwu as kw >>> p = kw.core.Placeholder('p') >>> a = kw.core.Binary('a') >>> y = p * a >>> str(y) '(p)*a' >>> y= y.feed({'p': 2}) >>> str(y) '2*a'
- get_average_coefficient()#
Return the average value of coefficients
- get_max_deltas()#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- get_variables()#
Get the set of variable names
- Returns:
dict: returnexpressionvariable
- kaiwu.core.quicksum(qubo_expr_list: list)[source]#
High-performance QUBO summator.
- Args:
qubo_expr_list (QUBO list): List of QUBO expressions for summation.
- Returns:
BinaryExpression: Constrained QUBO.
- Examples:
>>> import kaiwu as kw >>> qubo_list = [kw.core.Binary(f"b{i}") for i in range(10)] # Variables are also QUBO >>> output = kw.core.quicksum(qubo_list) >>> str(output) 'b0+b1+b2+b3+b4+b5+b6+b7+b8+b9'
- class kaiwu.core.Placeholder(name: str = '')[source]#
Bases:
BinaryExpressionPlaceholder variable: only stores the variable name, for decision-making
- clear() None#
Set the expression to 0
- feed(feed_dict)#
Assign values to placeholders and return a new expression object after assignment
- Args:
feed_dict(dict): Values for placeholders to be assigned
- Examples:
>>> import kaiwu as kw >>> p = kw.core.Placeholder('p') >>> a = kw.core.Binary('a') >>> y = p * a >>> str(y) '(p)*a' >>> y= y.feed({'p': 2}) >>> str(y) '2*a'
- get_average_coefficient()#
Return the average value of coefficients
- get_max_deltas()#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- get_variables()#
Get the set of variable names
- Returns:
dict: returnexpressionvariable
- class kaiwu.core.Integer(name: str = '', min_value=0, max_value=127)[source]#
Bases:
BinaryExpressionInteger variable: only stores the variable name and range, does not inherit QuboExpression
- clear() None#
Set the expression to 0
- feed(feed_dict)#
Assign values to placeholders and return a new expression object after assignment
- Args:
feed_dict(dict): Values for placeholders to be assigned
- Examples:
>>> import kaiwu as kw >>> p = kw.core.Placeholder('p') >>> a = kw.core.Binary('a') >>> y = p * a >>> str(y) '(p)*a' >>> y= y.feed({'p': 2}) >>> str(y) '2*a'
- get_average_coefficient()#
Return the average value of coefficients
- get_max_deltas()#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- get_variables()#
Get the set of variable names
- Returns:
dict: returnexpressionvariable
- kaiwu.core.ndarray(shape: int | Tuple[int, ...] | List[int], name, var_func, var_func_param=None)[source]#
QUBO container based on np.ndarray. This container supports various native NumPy vectorized operations
- Args:
shape (Union[int, Tuple[int, …]]): Shape
name (str): Identifier of the generated variable.
var_func (class or function): Method or class used to generate elements. The first parameter must be ‘name’
var_func_param (tuple): Parameters of var_func except ‘name’
- Returns:
np.ndarray: Multi-dimensional container.
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> A = kw.core.ndarray((2,3,4), "A", kw.core.Binary) >>> A BinaryExpressionNDArray([[[A[0][0][0], A[0][0][1], A[0][0][2], A[0][0][3]], [A[0][1][0], A[0][1][1], A[0][1][2], A[0][1][3]], [A[0][2][0], A[0][2][1], A[0][2][2], A[0][2][3]]], [[A[1][0][0], A[1][0][1], A[1][0][2], A[1][0][3]], [A[1][1][0], A[1][1][1], A[1][1][2], A[1][1][3]], [A[1][2][0], A[1][2][1], A[1][2][2], A[1][2][3]]]], dtype=object) >>> A[1,2] BinaryExpressionNDArray([A[1][2][0], A[1][2][1], A[1][2][2], A[1][2][3]], dtype=object) >>> A[:, [0,2]] BinaryExpressionNDArray([[[A[0][0][0], A[0][0][1], A[0][0][2], A[0][0][3]], [A[0][2][0], A[0][2][1], A[0][2][2], A[0][2][3]]], [[A[1][0][0], A[1][0][1], A[1][0][2], A[1][0][3]], [A[1][2][0], A[1][2][1], A[1][2][2], A[1][2][3]]]], dtype=object) >>> B = kw.core.ndarray(3, "B", kw.core.Binary) >>> B BinaryExpressionNDArray([B[0], B[1], B[2]], dtype=object) >>> C = kw.core.ndarray([3,3], "C", kw.core.Binary) >>> C BinaryExpressionNDArray([[C[0][0], C[0][1], C[0][2]], [C[1][0], C[1][1], C[1][2]], [C[2][0], C[2][1], C[2][2]]], dtype=object) >>> D = 2 * B.dot(C) + 2 >>> str(D[0]) '2*B[0]*C[0][0]+2*B[1]*C[1][0]+2*B[2]*C[2][0]+2' >>> E = B.sum() >>> str(E) 'B[0]+B[1]+B[2]' >>> F = np.diag(C) >>> F BinaryExpressionNDArray([C[0][0], C[1][1], C[2][2]], dtype=object)
- kaiwu.core.zeros(shape) BinaryExpressionNDArray[source]#
Create a zero array with the same shape as the input array.
- Args:
shape (tuple): matrix
- Returns:
QUBOArray: array with the same shape and all elements set to 0.
- Examples:
>>> import kaiwu as kw >>> Z = kw.core.zeros((2, 3)) >>> Z BinaryExpressionNDArray([[0, 0, 0], [0, 0, 0]], dtype=object)
- kaiwu.core.dot(mat_left, mat_right)[source]#
Matrix multiplication
- Args:
mat_left (numpy.array): First matrix
mat_right (numpy.array): Second matrix
- Raises:
ValueError: Both inputs must be np.ndarray. ValueError: Dimensions of the two inputs must match
- Returns:
np.ndarray: Product matrix
- class kaiwu.core.BinaryExpressionNDArray[source]#
Bases:
ndarrayQUBO container based on np.ndarray. This container supports various native NumPy vectorized operations
- is_array_less = <numpy.vectorize object>#
- is_array_less_equal = <numpy.vectorize object>#
- is_array_greater = <numpy.vectorize object>#
- is_array_greater_equal = <numpy.vectorize object>#
- is_array_equal = <numpy.vectorize object>#
- dot(b, out=None)[source]#
Matrix multiplication using quicksum
- Args:
b (BinaryExpressionNDArray): Another matrix
out: Optional output array used to store the results. It must match the expected output shape.
- Returns:
BinaryExpressionNDArray: Product
- sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True)[source]#
Summation method using quicksum
- Args:
axis: Specifies the axis (dimension) for summation. The default is None, which means summing over all elements; if it is an integer or tuple, summing is performed along the specified axis.
dtype: Specifies the output data type. If not provided, the input array’s dtype is used by default, but integer types may be upgraded to platform integer precision. Not currently supported.
out: Optional output array used to store the results. It must match the expected output shape.
keepdims: Boolean value. If True, the axis being summed is retained as a dimension of length 1. Not currently supported.
initial: The initial value (scalar) for summation, which defaults to 0. Not currently supported.
where: A boolean array specifying which elements are included in the summation (supported in NumPy 1.20+). Not currently supported.
- Returns:
BinaryExpressionNDArray: Product
- get_val(sol_dict)[source]#
Substitute spin values into QUBO array variables based on the result dictionary.
- Args:
array (QUBOArray): QUBO array
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
np.ndarray: Value array obtained after substituting into the QUBO array
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> x = kw.core.ndarray((2, 2), "x", kw.core.Binary) >>> y = x.sum() >>> y_vars = y.get_variables() >>> s = np.array([1, -1, 1, -1]) >>> sol_dict = kw.core.get_sol_dict(s, y_vars) >>> x.get_val(sol_dict) array([[1., 0.], [1., 0.]])
- class kaiwu.core.IsingModel(variables, ising_matrix, bias)[source]#
Bases:
dictIsing model
- fromkeys(value=None, /)#
Create a new dictionary with keys from iterable and values set to value.
- class kaiwu.core.IsingExpression(variables=None, quadratic=None, linear=None, bias=0)[source]#
Bases:
ExpressionBase class for Ising expressions; directly inherits Expression and preserves extension points.
- clear() None#
Set the expression to 0
- get_average_coefficient()#
Return the average value of coefficients
- get_max_deltas()#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- get_variables()#
Get the set of variable names
- Returns:
dict: returnexpressionvariable
- class kaiwu.core.Spin(name: str = '')[source]#
Bases:
IsingExpressionSpin variable; possible values are only -1 and 1.
- Args:
name (str): unique identifier of the variable.
- Returns:
dict: spin variable named name.
- Examples:
>>> import kaiwu as kw >>> s = kw.core.Spin("s") >>> s 2*s-1
- clear() None#
Set the expression to 0
- get_average_coefficient()#
Return the average value of coefficients
- get_max_deltas()#
Calculate the upper bound of the objective function change caused by flipping each variable. The return values negative_delta and positive_delta are the maximum changes caused by flipping the variable from 1->0 and 0->1, respectively.
- get_val(sol_dict)#
Substitute spin values into QUBO variables based on the result dictionary.
- Args:
qubo (QUBO expression): QUBO expression
sol_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- Examples:
>>> import kaiwu as kw >>> import numpy as np >>> a = kw.core.Binary("a") >>> b = kw.core.Binary("b") >>> c = kw.core.Binary("c") >>> d = a + 2 * b + 4 * c >>> sol_dict = {"a": 1, "b": 0, "c": 1} >>> d.get_val(sol_dict) 5
- get_variables()#
Get the set of variable names
- Returns:
dict: returnexpressionvariable
- class kaiwu.core.QuboModel(objective=None)[source]#
Bases:
BinaryModelQUBO model class that supports adding constraints
- Args:
objective (QuboExpression, optional): objective function. defaultNone
- make()[source]#
Return the merged QUBO expression
- Returns:
BinaryExpression: merged constraint expression
- add_constraint(constraint_in, name=None, constr_type: Literal['soft', 'hard'] = 'hard', penalty=1, slack_var_expr=None)#
Add constraint terms; single or multiple constraints are supported
- Args:
constraint_in: constraint expression; two input types are supported:
Single constraint: BinaryExpression Constraint for example:
quicksum(x) - 1Constraint(quicksum(x) - 1, "==", 1)Multiple constraints: list/tuple/np.ndarray, automatically iterated and added one by one for example:
[constraint1, constraint2, constraint3]
- name (str or list, optional): constraint name, automatically named by default. when multiple constraints are provided,
If a string is passed, it is used as a common prefix; if a list of strings is passed, it must match the number of constraints.
penalty (float, optional): default penalty coefficient
constr_type(str, optional): Constraint type, can be set to “soft” or “hard”, defaults to “hard”
- slack_var_expr (BinaryExpression, optional): slack variable expression, used only in inequality constraints,
generated automatically by default
- Example1 (Single BinaryExpression):
>>> import kaiwu as kw >>> model = kw.core.QuboModel() >>> x = [kw.core.Binary(f"x{i}") for i in range(3)] >>> model.add_constraint(kw.core.quicksum(x) - 1)
- Example2 (Constraint with relation operator):
>>> from kaiwu.core._constraint import Constraint >>> model.add_constraint(Constraint(kw.core.quicksum(x) - 1, "==", 1))
- Examples3 (Multiple Constraints):
>>> constraints = [x[i] - 1 for i in range(3)] >>> model.add_constraint(constraints, name="my_constraints")
- compile_constraints()#
Convert constraint terms to Expression according to different styles
- get_constraints_expr_list()#
Get all current constraints.
- Returns:
list: list of all constraints.
- get_value(solution_dict)#
Substitute variable values into QUBO variables based on the result dictionary.
- Args:
solution_dict (dict): Result dictionary generated by get_sol_dict.
- Returns:
float: Value obtained after substituting into the QUBO
- initialize_penalties()#
Automatically initialize all penalty coefficients
- set_constraint_handler(constraint_handler)#
Set the unconstrained conversion method for constraint terms
- Args:
constraint_handler: Class for setting the unconstrained representation method of constraint terms
- set_objective(objective)#
Set the objective function
- Args:
objective (BinaryExpression): Objective function expression
- verify_constraint(solution_dict, constr_type: Literal['soft', 'hard'] = 'hard')#
Verify whether constraints are satisfied
- Args:
solution_dict (dict): QUBO model solution dictionary
constr_type(str, optional): Constraint type, can be set to “soft” or “hard”, defaults to “hard”
- Returns:
- tuple: Constraint satisfaction information
int: Number of unsatisfied constraints
dict: Dictionary containing constraint values
- kaiwu.core.calculate_qubo_value(qubo_matrix, offset, binary_configuration)[source]#
Q value calculator.
- Args:
qubo_matrix (np.ndarray): QUBOmatrix.
offset (float): constant term
binary_configuration (np.ndarray): binary configuration
- Returns:
output (float): Q value.
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> matrix = np.array([[1., 0., 0.], ... [0., 1., 0.], ... [0., 0., 1.]]) >>> offset = 1.8 >>> binary_configuration = np.array([0, 1, 0]) >>> qubo_value = kw.core.calculate_qubo_value(matrix, offset, binary_configuration) >>> print(qubo_value) 2.8
- kaiwu.core.qubo_matrix_to_qubo_model(qubo_mat)[source]#
Convert a QUBO matrix to a QUBO model
- Args:
qubo_mat (np.ndarray): QUBOmatrix
- Returns:
QuboModel: QUBO model
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> matrix = -np.array([[0, 8], ... [0, 0]]) >>> kw.core.qubo_matrix_to_qubo_model(matrix).objective -8*b[0]*b[1]
- kaiwu.core.ising_matrix_to_qubo_matrix(ising_mat, remove_linear_bit=True, decimal=False)[source]#
Convert an Ising matrix to a QUBO matrix
- Args:
ising_mat (np.ndarray): Isingmatrix
remove_linear_bit (bool): An auxiliary variable is added to represent linear terms when converting QUBO to Ising. Whether to remove the last spin variable. Defaults to True.
decimal (bool): whether to use Decimal for high-precision computation; defaults to False.
- Returns:
tuple: QUBO matrix and bias
qubo_mat (np.ndarray): QUBOmatrix
bias (float): constant term difference between QUBO and Ising
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> matrix = -np.array([[ 0. , 1. , 0. , 1. , 1. ], ... [ 1. , 0. , 0. , 1., 1. ], ... [ 0. , 0. , 0. , 1., 1. ], ... [ 1. , 1., 1. , 0. , 1. ], ... [ 1. , 1., 1. , 1. , 0. ]]) >>> _qubo_mat, _ = kw.core.ising_matrix_to_qubo_matrix(matrix) >>> _qubo_mat array([[-4., 8., 0., 8.], [-0., -4., 0., 8.], [-0., -0., -0., 8.], [-0., -0., -0., -8.]])
- kaiwu.core.qubo_matrix_to_ising_matrix(qubo_mat, decimal=False)[source]#
Convert a QUBO matrix to an Ising matrix
- Args:
qubo_mat (np.ndarray): QUBOmatrix
decimal (bool): whether to use Decimal for high-precision computation; defaults to False.
- Returns:
- tuple: Ising matrix and bias
ising_mat (np.ndarray): Isingmatrix
bias (float): constant term difference between QUBO and Ising
- Examples:
>>> import numpy as np >>> import kaiwu as kw >>> matrix = -np.array([[-4., 8., 0., 8.], ... [-0., -4., 0., 8.], ... [-0., -0., -0., 8.], ... [-0., -0., -0., -8.]]) >>> _ising_mat, _ = kw.core.qubo_matrix_to_ising_matrix(matrix) >>> _ising_mat array([[-0., 1., -0., 1., 1.], [ 1., -0., -0., 1., 1.], [-0., -0., -0., 1., 1.], [ 1., 1., 1., -0., 1.], [ 1., 1., 1., 1., -0.]])
- kaiwu.core.qubo_model_to_ising_model(qubo_model)[source]#
Convert QUBO to a Ising model.
- Args:
qubo_model (QuboModel): QUBO Model.
- Returns:
CimIsing: Ising model.
- Examples:
>>> import kaiwu as kw >>> b1, b2 = kw.core.Binary("b1"), kw.core.Binary("b2") >>> q = b1 + b2 + b1*b2 >>> q_model = kw.core.QuboModel(q) >>> ci = kw.core.qubo_model_to_ising_model(q_model) >>> print(str(ci)) Ising Details: Ising Matrix: [[-0. -0.125 -0.375] [-0.125 -0. -0.375] [-0.375 -0.375 -0. ]] Ising Bias: 1.25 Ising Variables: b1, b2, __spin__