# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# obtain a copy of this license in the LICENSE.txt file in the root directory
#
# 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.

from enum import Enum
from typing import Union, List, Dict, Tuple, Any

from numpy import ndarray
from scipy.sparse import spmatrix

from .linear_constraint import LinearExpression

class ObjSense(Enum):
"""Objective Sense Type."""
MINIMIZE = 1
MAXIMIZE = -1

"""Representation of quadratic objective function of the form:
constant + linear * x + x * quadratic * x.
"""

Sense = ObjSense

constant: float = 0.0,
linear: Union[ndarray, spmatrix, List[float], Dict[Union[str, int], float]] = None,
Dict[Tuple[Union[int, str], Union[int, str]], float]] = None,
sense: ObjSense = ObjSense.MINIMIZE
) -> None:

Args:
constant: The constant offset of the objective.
linear: The coefficients of the linear part of the objective.
sense: The optimization sense of the objective.
"""
self._constant = constant
if linear is None:
linear = {}
self._sense = sense

@property
def constant(self) -> float:
"""Returns the constant part of the objective function.

Returns:
The constant part of the objective function.
"""
return self._constant

@constant.setter
def constant(self, constant: float) -> None:
"""Sets the constant part of the objective function.

Args:
constant: The constant part of the objective function.
"""
self._constant = constant

@property
def linear(self) -> LinearExpression:
"""Returns the linear part of the objective function.

Returns:
The linear part of the objective function.
"""
return self._linear

@linear.setter
def linear(self, linear: Union[ndarray, spmatrix, List[float], Dict[Union[str, int], float]]
) -> None:
"""Sets the coefficients of the linear part of the objective function.

Args:
linear: The coefficients of the linear part of the objective function.

"""

@property
"""Returns the quadratic part of the objective function.

Returns:
The quadratic part of the objective function.
"""

Dict[Tuple[Union[int, str], Union[int, str]], float]]
) -> None:
"""Sets the coefficients of the quadratic part of the objective function.

Args:

"""

@property
def sense(self) -> ObjSense:
"""Returns the sense of the objective function.

Returns:
The sense of the objective function.
"""
return self._sense

@sense.setter
def sense(self, sense: ObjSense) -> None:
"""Sets the sense of the objective function.

Args:
sense: The sense of the objective function.
"""
self._sense = sense

[Doku]    def evaluate(self, x: Union[ndarray, List, Dict[Union[int, str], float]]) -> float:
"""Evaluate the quadratic objective for given variable values.

Args:
x: The values of the variables to be evaluated.

Returns:
The value of the quadratic objective given the variable values.
"""
return self.constant + self.linear.evaluate(x) + self.quadratic.evaluate(x)

[Doku]    def evaluate_gradient(self, x: Union[ndarray, List, Dict[Union[int, str], float]]) -> ndarray: