.. _opttask-py: ########## opttask.py ########## SIMO Optimization task definition:: >>> epsilon = 0.00001 >>> from lxml import etree >>> import datetime >>> from simo.builder.optimization.opttask import OptimizationTaskDef >>> tdf = open('../../simulator/xml/schemas/Typedefs_SIMO.xsd') >>> typedef = tdf.read() >>> tdf.close() >>> sf = open('../../simulator/xml/schemas/optimization_task.xsd') >>> schema = sf.read() >>> sf.close() >>> xml = ''' ... 2008-01-01 ... year ... comp_unit:SC eq 3 ... 3.0 ... ... ... comp_unit:PRICE_REGION le 4 ... 3.0 ... ... ... comp_unit:PRICE_REGION eq 5 ... 2.0 ... ... ... ... comp_unit ... ... additive ... max ... global ... ... ... ... 1.0 ... ... sum[1:10](operation:cash_flow:discount) ... ... ... linear ... ... ... ... ... ... sum[6:10](operation:cash_flow) / ... sum[1:5](operation:cash_flow) lt 1.3 ... ... ... sum[6:10](operation:cash_flow) / ... sum[1:5](operation:cash_flow) gt 0.7 ... ... ... ... ''' ************************************* class OptimizationTaskDef(XmlObject): ************************************* def __init__(self, typedef): ============================ >>> class Lexicon(object): ... def get_level_ind(self, level): ... return 1 ... def get_variable_ind(self, level, var, active=False): ... return (1, 1) >>> otd = OptimizationTaskDef(typedef) >>> otd.schema = schema >>> try: ... otd.xml = xml ... except ValueError, e: ... print e name, xml content and lexicon instance must be passed >>> otd.xml = ('optimization-task', xml, Lexicon()) >>> otd.xml['optimization-task'][0:18] '>> opt = otd.obj['optimization-task'] def _parse(self, root): ======================= Parse optimization task definition XML :: >>> opt.init_date datetime.date(2008, 1, 1) >>> opt.period_step 'year' >>> opt.discount_rate 3.0 >>> opt.main_level 'comp_unit' >>> opt.data_filter # doctest: +ELLIPSIS [('data', ('comp_unit', 'SC')), ('value', 3.0), ('eq', )] >>> opt.conditional_discounting # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [('comp_unit:PRICE_REGION le 4', [('data', ('comp_unit', 'PRICE_REGION')), ('value', 4.0), ('eq', )], 3.0), ('comp_unit:PRICE_REGION eq 5', [('data', ('comp_unit', 'PRICE_REGION')), ('value', 5.0), ('eq', )], 2.0)] Parameters : root -- XML root element def _parse_conditional_discount(self, elem): ============================================ Parse conditional discounting rates def _parse_data_filter(self, elem): =================================== Parse optimization data filter expression def _parse_date(self, elem): ============================ Parse date expression from xs:date format into datetime.date object:: >>> xml = u'''2008-01-01''' >>> elem = etree.fromstring(xml) >>> opt._parse_date(elem) datetime.date(2008, 1, 1) >>> xml = u'''today''' >>> elem = etree.fromstring(xml) >>> opt._parse_date(elem) == datetime.date.today() True def _parse_objective_func(self, elem): ====================================== Parse objective function definition:: >>> opt._objective_func.type 'additive' >>> opt._objective_func.target 'max' >>> opt._objective_func.scope 'global' def _parse_subobjectives(self, elem): ===================================== Parse objective function subobjectives:: >>> for i in opt._subobjectives[0].expr: print i # doctest: +ELLIPSIS ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)), None, True, (0, 0)) ('aggr', ) def _parse_constraints(self, elem): =================================== Parse optimization task constraint expressions:: >>> for i in opt._constraints[0].expr: ... if i[0] != 'value': ... print i ... else: ... print (i[0], '%.2f' % i[1]) ... # doctest: +ELLIPSIS ('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (1, 1)) ('aggr', ) ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (2, 1)) ('aggr', ) ('ari', , '/') ('value', '1.30') ('eq', , 'lt') >>> for i in opt._constraints[1].expr: ... if i[0] != 'value': ... print i ... else: ... print (i[0], '%.2f' % i[1]) ... # doctest: +ELLIPSIS ('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (3, 1)) ('aggr', ) ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (4, 1)) ('aggr', ) ('ari', , '/') ('value', '0.70') ('eq', , 'gt') def _parse_utility_function(self, elem): ======================================== Parse subobjective utility function definition:: >>> xml = u''' ... linear ... ''' >>> elem = etree.fromstring(xml) >>> ufunc = opt._parse_utility_function(elem) >>> ufunc.type 'linear' def _unify_operands(self): ========================== Go through each subobjective constraint expression and all operands of each expression and construct index of unique operands. All subobjective and constraint operands are mapped to unique operands and in optimization data matrix, all data processing is done to the unique operands which saves a lot of memory with large data sets. Unique operands contain variable name, level, constraint and discounting info (no date information) :: >>> opt._unify_operands() >>> opt._operand_index[0] 0 >>> opt._operand_index[1] 1 >>> opt._operand_index[2] 1 >>> opt._operand_index[3] 1 >>> opt._operand_index[4] 1 >>> opt._unique_operands[('op', u'cash_flow', None, True)] 0 >>> opt._unique_operands[('op', u'cash_flow', None, False)] 1 >>> opt.date_ranges[0] (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)) >>> opt.date_ranges[1] (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)) def _process_expression(self, expression, expr_type, i): ======================================================== Process a single subobjective or constraint expression and update unique operand index Parameters:: expression -- parsed expression in postfix form expr_type -- expression type, either 's' for subobjective or 'c' for constraint i -- expression indice def update_init_date(self, new_date): ===================================== Give new initial date, and fix all subobjectives to match. Parameters :: new_date -- a datetime.date object >>> opt._init_date datetime.date(2008, 1, 1) >>> for subobj in opt._subobjectives: print subobj.expr ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)), None, True, (0, 0), (5, 2)), ('aggr', )] >>> print [c.expr for c in opt._constraints] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [[('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (1, 1), (6, 3)), ('aggr', ), ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (2, 1), (7, 4)), ('aggr', ), ('ari', , '/'), ('value', 1.3), ('eq', , 'lt')], [('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (3, 1), (8, 5)), ('aggr', ), ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (4, 1), (9, 6)), ('aggr', ), ('ari', , '/'), ('value', 0...), ('eq', , 'gt')]] >>> opt.update_init_date(datetime.date(2012, 12, 13)) >>> opt._init_date datetime.date(2012, 12, 13) >>> for subobj in opt._subobjectives: print subobj.expr ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [('op', u'cash_flow', (datetime.date(2012, 12, 13), datetime.date(2022, 12, 12)), None, True, (0, 0), (5, 2)), ('aggr', )] >>> print [c.expr for c in opt._constraints] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [[('op', u'cash_flow', (datetime.date(2017, 12, 13), datetime.date(2022, 12, 12)), None, False, (1, 1), (6, 3)), ('aggr', ), ('op', u'cash_flow', (datetime.date(2012, 12, 13), datetime.date(2017, 12, 12)), None, False, (2, 1), (7, 4)), ('aggr', ), ('ari', , '/'), ('value', 1.3), ('eq', , 'lt')], [('op', u'cash_flow', (datetime.date(2017, 12, 13), datetime.date(2022, 12, 12)), None, False, (3, 1), (8, 5)), ('aggr', ), ('op', u'cash_flow', (datetime.date(2012, 12, 13), datetime.date(2017, 12, 12)), None, False, (4, 1), (9, 6)), ('aggr', ), ('ari', , '/'), ('value', 0...), ('eq', , 'gt')]] >>> opt.update_init_date(datetime.date(2008, 1, 1)) >>> for subobj in opt._subobjectives: print subobj.expr ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)), None, True, (0, 0), (5, 2)), ('aggr', )] >>> print [c.expr for c in opt._constraints] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [[('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (1, 1), (6, 3)), ('aggr', ), ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (2, 1), (7, 4)), ('aggr', ), ('ari', , '/'), ('value', 1.3), ('eq', , 'lt')], [('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (3, 1), (8, 5)), ('aggr', ), ('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (4, 1), (9, 6)), ('aggr', ), ('ari', , '/'), ('value', 0...), ('eq', , 'gt')]]