kaiwu.core package#
Module contents#
Module: core
Function: Definition of Baseses
- class kaiwu.core.OptimizerBase#
Bases:
objectBases for Ising solvers
- set_matrix(ising_matrix)#
Set matrix and update related content
- on_matrix_change()#
Update matrix-related information; can be implemented when inheriting from OptimizerBase. When the Ising matrix being processed changes, the implementation of this function will be called to allow corresponding actions.
- solve(ising_matrix=None)#
Solve
- class kaiwu.core.SolverBase(optimizer)#
Bases:
objectBases for Solvers
- Args:
optimizer (OptimizerBase): Ising solver
- solve_qubo(*args, **kwargs)#
- exception kaiwu.core.KaiwuError#
Bases:
ExceptionBases for exceptions in this module.
- args#
- with_traceback()#
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- class kaiwu.core.ConstraintDefinition(expr_left, relation, expected_value=0)#
Bases:
objectConstraint Definition Args:
expr_left (Expression): Left operator of the constraint term
relation (string): Relational operator
expected_value(float): Right operator of the constraint term, default is 0
- is_satisfied(solution_dict)#
Verify constraint satisfaction
- kaiwu.core.get_min_penalty(obj, cons)#
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("b"+str(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)#
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)#
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("b"+str(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')#
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("b"+str(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)#
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: ConstraintDefinition, parent_model)#
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.
- set_penalty(penalty)#
Set penalty coefficient
- penalize_more()#
Increase penalty coefficient
- penalize_less()#
Decrease penalty coefficient
- is_satisfied(solution_dict)#
Verify constraint satisfaction
- kaiwu.core.get_sol_dict(solution, vars_dict)#
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.qubo.QuboModel(d) >>> d_ising = kw.conversion.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_array_val(array, sol_dict)#
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 = kw.qubo.QuboModel(y) >>> y_ising = kw.conversion.qubo_model_to_ising_model(y) >>> ising_vars = y_ising.get_variables() >>> s = np.array([1, -1, 1, -1]) >>> sol_dict = kw.core.get_sol_dict(s, ising_vars) >>> kw.core.get_array_val(x, sol_dict) array([[1., 0.], [1., 0.]])
- kaiwu.core.get_val(qubo, 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 >>> qubo_model = kw.qubo.QuboModel(d) >>> d_ising = kw.conversion.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)
- kaiwu.core.update_constraint(qubo_origin, qubo_result)#
Update the constraints and reduced-order constraint information of qexp to q
- class kaiwu.core.Expression(coefficient: dict | None = None, offset: float = 0)#
Bases:
dictUniversal Bases for QUBO/Ising expressions (provides default quadratic expression implementation)
- clear() None. Remove all items from D.#
- get_variables()#
Get the set of variable names
- Returns:
variables: (tuple) Returns the set of variables composing the expression
- 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.
- fromkeys(value=None, /)#
Create a new dictionary with keys from iterable and values set to value.
- get_average_coefficient()#
Return the average value of coefficients
- kaiwu.core.expr_add(expr_left, expr_right, expr_result)#
Addition of universal quadratic expressions
- kaiwu.core.expr_mul(expr_left, expr_right, expr_result)#
Multiplication of universal quadratic expressions
- kaiwu.core.expr_neg(expr_origin, expr_result)#
Negation of universal quadratic expressions
- kaiwu.core.expr_pow(expr_left, expr_right, expr_result)#
Exponentiation of universal quadratic expressions; requires expr_right to be 1 or 2 only
- class kaiwu.core.BinaryModel(objective=None)#
Bases:
objectBinary model class
- Args:
objective (BinaryExpression, optional): Objective function. Defaults to None
- 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
- add_constraint(constraint_in, name=None, constr_type: Literal['soft', 'hard'] = 'hard', penalty=None)#
Add constraint terms (supports single or multiple constraints)
- Args:
constraint_in (ConstraintDefinition or iterable): The constraint expression or its iterable object.
name (str or list, optional): Constraint name or list of names; automatically named by default.
constr_type(str, optional): Constraint type, can be set to “soft” or “hard”, defaults to “hard”
penalty (float): Default penalty coefficient
- 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
- 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
- initialize_penalties()#
Automatically initialize all penalty coefficients
- get_constraints_expr_list()#
Get all current constraints.
- Returns:
List of all constraints.
- compile_constraints()#
Convert constraint terms to Expression according to different styles. For inequality constraints, the penalty function method is currently supported.
- class kaiwu.core.BinaryExpression(coefficient: dict | None = None, offset: float = 0, name='')#
Bases:
ExpressionBasic data structure for QUBO expressions
- 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'
- clear() None. Remove all items from D.#
- fromkeys(value=None, /)#
Create a new dictionary with keys from iterable and values set to value.
- 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_variables()#
Get the set of variable names
- Returns:
variables: (tuple) Returns the set of variables composing the expression
- class kaiwu.core.Binary(name: str = '')#
Bases:
BinaryExpressionBinary variable: only stores the variable name, does not inherit QuboExpression
- clear() None. Remove all items from D.#
- 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'
- fromkeys(value=None, /)#
Create a new dictionary with keys from iterable and values set to value.
- 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_variables()#
Get the set of variable names
- Returns:
variables: (tuple) Returns the set of variables composing the expression
- kaiwu.core.quicksum(qubo_expr_list: list)#
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("b"+str(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 = '')#
Bases:
BinaryExpressionPlaceholder variable: only stores the variable name, for decision-making
- get_placeholder_set()#
Get the set of placeholders
- clear() None. Remove all items from D.#
- 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'
- fromkeys(value=None, /)#
Create a new dictionary with keys from iterable and values set to value.
- 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_variables()#
Get the set of variable names
- Returns:
variables: (tuple) Returns the set of variables composing the expression
- class kaiwu.core.Integer(name: str = '', min_value=0, max_value=127)#
Bases:
BinaryExpressionInteger variable: only stores the variable name and range, does not inherit QuboExpression
- clear() None. Remove all items from D.#
- 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'
- fromkeys(value=None, /)#
Create a new dictionary with keys from iterable and values set to value.
- 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_variables()#
Get the set of variable names
- Returns:
variables: (tuple) Returns the set of variables composing the expression
- kaiwu.core.ndarray(shape: int | Tuple[int, ...] | List[int], name, var_func, var_func_param=None)#
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.dot(mat_left, mat_right)#
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#
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)#
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)#
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