Source code for pystoned.ICNLS

# import dependencies
from pyomo.environ import Constraint
from pyomo.core.expr.numvalue import NumericValue
import numpy as np
from . import CNLS
from .constant import CET_ADDI, CET_MULT, FUN_PROD, FUN_COST, RTS_CRS, RTS_VRS


[docs] class ICNLS(CNLS.CNLS): """Isotonic Convex Nonparametric Least Square (ICNLS)"""
[docs] def __init__(self, y, x, z=None, cet=CET_ADDI, fun=FUN_PROD, rts=RTS_VRS): """ICNLS model Args: y (float): output variable. x (float): input variables. z (float, optional): Contextual variable(s). Defaults to None. cet (String, optional): CET_ADDI (additive composite error term) or CET_MULT (multiplicative composite error term). Defaults to CET_ADDI. fun (String, optional): FUN_PROD (production frontier) or FUN_COST (cost frontier). Defaults to FUN_PROD. rts (String, optional): RTS_VRS (variable returns to scale) or RTS_CRS (constant returns to scale). Defaults to RTS_VRS. """ super().__init__(y, x, z, cet, fun, rts) self.__pmatrix = self.__binaryMatrix() self.__model__.afriat_rule.deactivate() self.__model__.isotonic_afriat_rule = Constraint(self.__model__.I, self.__model__.I, rule=self.__isotonic_afriat_rule(), doc='isotonic afriat inequality')
def __isotonic_afriat_rule(self): """Return the proper afriat inequality constraint""" if self.fun == FUN_PROD: __operator = NumericValue.__le__ elif self.fun == FUN_COST: __operator = NumericValue.__ge__ if self.cet == CET_ADDI: if self.rts == RTS_VRS: def afriat_rule(model, i, h): if i == h or self.__pmatrix[i][h] == 0: return Constraint.Skip return __operator( self.__pmatrix[i][i] * (model.alpha[i] + sum( model.beta[i, j] * self.x[i][j] for j in model.J)), self.__pmatrix[i][h] * (model.alpha[h] + sum( model.beta[h, j] * self.x[i][j] for j in model.J)) ) return afriat_rule elif self.rts == RTS_CRS: def afriat_rule(model, i, h): if i == h or self.__pmatrix[i][h] == 0: return Constraint.Skip return __operator( self.__pmatrix[i][i] * sum( model.beta[i, j] * self.x[i][j] for j in model.J), self.__pmatrix[i][h] * sum( model.beta[h, j] * self.x[i][j] for j in model.J) ) return afriat_rule elif self.cet == CET_MULT: if self.rts == RTS_VRS: def afriat_rule(model, i, h): if (i == h) or (self.__pmatrix[i][h] == 0): return Constraint.Skip return __operator( self.__pmatrix[i][i] * (model.alpha[i] + sum( model.beta[i, j] * self.x[i][j] for j in model.J)), self.__pmatrix[i][h] * (model.alpha[h] + sum( model.beta[h, j] * self.x[i][j] for j in model.J)) ) return afriat_rule elif self.rts == RTS_CRS: def afriat_rule(model, i, h): if (i == h) or (self.__pmatrix[i][h] == 0): return Constraint.Skip return __operator( self.__pmatrix[i][i] * (sum(model.beta[i, j] * self.x[i][j] for j in model.J)), self.__pmatrix[i][h] * (sum(model.beta[h, j] * self.x[i][j] for j in model.J)) ) return afriat_rule # TODO(error handling): replace with undefined model attribute return False def __binaryMatrix(self): """generating binary matrix P""" # transform data x = np.array(self.x) # number of DMUs n, m = len(x), len(x[0]) # binary matrix P p = np.zeros((n, n)) for i in range(n): pmap = (x[i, 0] <= x[:, 0]) for j in range(1, m): pmap = pmap & (x[i, j] <= x[:, j]) p[i, :] = np.where(pmap, 1, 0) return p.tolist()