Source code for qiskit.optimization.problems.linear_expression

# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Linear expression interface."""

from typing import List, Union, Dict, Any

from numpy import ndarray
from scipy.sparse import spmatrix, dok_matrix

from .quadratic_program_element import QuadraticProgramElement
from ..exceptions import QiskitOptimizationError


[docs]class LinearExpression(QuadraticProgramElement): """ Representation of a linear expression by its coefficients.""" def __init__(self, quadratic_program: Any, coefficients: Union[ndarray, spmatrix, List[float], Dict[Union[int, str], float]]) -> None: """Creates a new linear expression. The linear expression can be defined via an array, a list, a sparse matrix, or a dictionary that uses variable names or indices as keys and stores the values internally as a dok_matrix. Args: quadratic_program: The parent QuadraticProgram. coefficients: The (sparse) representation of the coefficients. """ super().__init__(quadratic_program) self.coefficients = coefficients
[docs] def __getitem__(self, i: Union[int, str]) -> float: """Returns the i-th coefficient where i can be a variable name or index. Args: i: the index or name of the variable corresponding to the coefficient. Returns: The coefficient corresponding to the addressed variable. """ if isinstance(i, str): i = self.quadratic_program.variables_index[i] return self.coefficients[0, i]
def __setitem__(self, i: Union[int, str], value: float) -> None: if isinstance(i, str): i = self.quadratic_program.variables_index[i] self._coefficients[0, i] = value def _coeffs_to_dok_matrix(self, coefficients: Union[ndarray, spmatrix, List, Dict[Union[int, str], float]] ) -> dok_matrix: """Maps given 1d-coefficients to a dok_matrix. Args: coefficients: The 1d-coefficients to be mapped. Returns: The given 1d-coefficients as a dok_matrix Raises: QiskitOptimizationError: if coefficients are given in unsupported format. """ if isinstance(coefficients, list) or \ isinstance(coefficients, ndarray) and len(coefficients.shape) == 1: coefficients = dok_matrix([coefficients]) elif isinstance(coefficients, spmatrix): coefficients = dok_matrix(coefficients) elif isinstance(coefficients, dict): coeffs = dok_matrix((1, self.quadratic_program.get_num_vars())) for index, value in coefficients.items(): if isinstance(index, str): index = self.quadratic_program.variables_index[index] coeffs[0, index] = value coefficients = coeffs else: raise QiskitOptimizationError("Unsupported format for coefficients.") return coefficients @property def coefficients(self) -> dok_matrix: """ Returns the coefficients of the linear expression. Returns: The coefficients of the linear expression. """ return self._coefficients @coefficients.setter def coefficients(self, coefficients: Union[ndarray, spmatrix, List[float], Dict[Union[str, int], float]] ) -> None: """Sets the coefficients of the linear expression. Args: coefficients: The coefficients of the linear expression. """ self._coefficients = self._coeffs_to_dok_matrix(coefficients)
[docs] def to_array(self) -> ndarray: """Returns the coefficients of the linear expression as array. Returns: An array with the coefficients corresponding to the linear expression. """ return self._coefficients.toarray()[0]
[docs] def to_dict(self, use_name: bool = False) -> Dict[Union[int, str], float]: """Returns the coefficients of the linear expression as dictionary, either using variable names or indices as keys. Args: use_name: Determines whether to use index or names to refer to variables. Returns: An dictionary with the coefficients corresponding to the linear expression. """ if use_name: return {self.quadratic_program.variables[k].name: v for (_, k), v in self._coefficients.items()} else: return {k: v for (_, k), v in self._coefficients.items()}
[docs] def evaluate(self, x: Union[ndarray, List, Dict[Union[int, str], float]]) -> float: """Evaluate the linear expression for given variables. Args: x: The values of the variables to be evaluated. Returns: The value of the linear expression given the variable values. """ # cast input to dok_matrix if it is a dictionary x = self._coeffs_to_dok_matrix(x) # compute the dot-product of the input and the linear coefficients val = (x @ self.coefficients.transpose())[0, 0] # return the result return val