Table Of Contents

Previous topic

objfunc.py

Next topic

aggrdef.py

This Page

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 = '''<optimization_task
...    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...    xsi:schemaLocation="http://www.simo-project.org/simo
...    ../schemas/optimization_task.xsd"
...    xmlns="http://www.simo-project.org/simo">
...       <initial_date>2008-01-01</initial_date>
...       <period_step>year</period_step>
...       <data_filter>comp_unit:SC eq 3</data_filter>
...       <discount_rate>3.0</discount_rate>
...       <conditional_discount>
...           <rate>
...                   <condition>comp_unit:PRICE_REGION le 4</condition>
...               <value>3.0</value>
...           </rate>
...           <rate>
...               <condition>comp_unit:PRICE_REGION eq 5</condition>
...               <value>2.0</value>
...           </rate>
...       </conditional_discount>
...       <objective_function>
...          <level>comp_unit</level>
...          <type>
...             <function>additive</function>
...             <target>max</target>
...             <scope>global</scope>
...          </type>
...          <sub_objectives>
...             <sub_objective>
...                <weight>1.0</weight>
...                <expression>
...                   sum[1:10](operation:cash_flow:discount)
...                </expression>
...                <utility_function>
...                   <type>linear</type>
...                </utility_function>
...             </sub_objective>
...          </sub_objectives>
...          <constraints>
...              <constraint max_violation="10" violation_metric="percentage">
...                  sum[6:10](operation:cash_flow) /
...                  sum[1:5](operation:cash_flow) lt 1.3
...              </constraint>
...              <constraint>
...                  sum[6:10](operation:cash_flow) /
...                  sum[1:5](operation:cash_flow) gt 0.7
...              </constraint>
...          </constraints>
...       </objective_function>
...   </optimization_task>'''

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]
'<optimization_task'

class OptimizationTask(object):

Optimization task definition

def __init__(self):

>>> 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  
[('data', ('comp_unit', 'SC')), ('value', 3.0), ('eq', <function eee at ...>)]
>>> opt.conditional_discounting  
[('comp_unit:PRICE_REGION le 4',
  [('data', ('comp_unit', 'PRICE_REGION')),
   ('value', 4.0), ('eq', <function lee at ...>)], 3.0),
 ('comp_unit:PRICE_REGION eq 5',
  [('data', ('comp_unit', 'PRICE_REGION')),
   ('value', 5.0), ('eq', <function eee at ...>)], 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'''<initial_date>2008-01-01</initial_date>'''
>>> elem = etree.fromstring(xml)
>>> opt._parse_date(elem)
datetime.date(2008, 1, 1)
>>> xml = u'''<initial_date>today</initial_date>'''
>>> 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 
('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2017, 12, 31)), None, True, (0, 0))
('aggr', <function sum at ...>)

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])
... 
('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (1, 1))
('aggr', <function sum at ...>)
('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (2, 1))
('aggr', <function sum at ...>)
('ari', <function divide at ...>, '/')
('value', '1.30')
('eq', <function lte at ...>, 'lt')
>>> for i in opt._constraints[1].expr:
...     if i[0] != 'value':
...         print i
...     else:
...         print (i[0], '%.2f' % i[1])
... 
('op', u'cash_flow', (datetime.date(2013, 1, 1), datetime.date(2017, 12, 31)), None, False, (3, 1))
('aggr', <function sum at ...>)
('op', u'cash_flow', (datetime.date(2008, 1, 1), datetime.date(2012, 12, 31)), None, False, (4, 1))
('aggr', <function sum at ...>)
('ari', <function divide at ...>, '/')
('value', '0.70')
('eq', <function gte at ...>, 'gt')

def _parse_utility_function(self, elem):

Parse subobjective utility function definition:

>>> xml = u'''<utility_function>
...     <type>linear</type>
... </utility_function>'''
>>> 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', <function sum at ...>)]
>>> 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', <function sum at ...>),
   ('op', u'cash_flow', (datetime.date(2008, 1, 1),
                         datetime.date(2012, 12, 31)),
   None, False, (2, 1), (7, 4)), ('aggr', <function sum at ...>),
   ('ari', <function divide at ...>, '/'), ('value', 1.3),
   ('eq', <function lte at ...>, 'lt')],
 [('op', u'cash_flow', (datetime.date(2013, 1, 1),
                        datetime.date(2017, 12, 31)),
   None, False, (3, 1), (8, 5)), ('aggr', <function sum at ...>),
   ('op', u'cash_flow', (datetime.date(2008, 1, 1),
                         datetime.date(2012, 12, 31)),
   None, False, (4, 1), (9, 6)), ('aggr', <function sum at ...>),
   ('ari', <function divide at ...>, '/'), ('value', 0...),
   ('eq', <function gte at ...>, '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', <function sum at ...>)]
>>> 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', <function sum at ...>),
   ('op', u'cash_flow', (datetime.date(2012, 12, 13),
                         datetime.date(2017, 12, 12)),
   None, False, (2, 1), (7, 4)), ('aggr', <function sum at ...>),
   ('ari', <function divide at ...>, '/'), ('value', 1.3),
   ('eq', <function lte at ...>, 'lt')],
 [('op', u'cash_flow', (datetime.date(2017, 12, 13),
                        datetime.date(2022, 12, 12)),
   None, False, (3, 1), (8, 5)), ('aggr', <function sum at ...>),
   ('op', u'cash_flow', (datetime.date(2012, 12, 13),
                         datetime.date(2017, 12, 12)),
   None, False, (4, 1), (9, 6)), ('aggr', <function sum at ...>),
   ('ari', <function divide at ...>, '/'), ('value', 0...),
   ('eq', <function gte at ...>, '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', <function sum at ...>)]
>>> 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', <function sum at ...>),
   ('op', u'cash_flow', (datetime.date(2008, 1, 1),
                         datetime.date(2012, 12, 31)),
   None, False, (2, 1), (7, 4)), ('aggr', <function sum at ...>),
   ('ari', <function divide at ...>, '/'), ('value', 1.3),
   ('eq', <function lte at ...>, 'lt')],
 [('op', u'cash_flow', (datetime.date(2013, 1, 1),
                        datetime.date(2017, 12, 31)),
   None, False, (3, 1), (8, 5)), ('aggr', <function sum at ...>),
   ('op', u'cash_flow', (datetime.date(2008, 1, 1),
                         datetime.date(2012, 12, 31)),
   None, False, (4, 1), (9, 6)), ('aggr', <function sum at ...>),
   ('ari', <function divide at ...>, '/'), ('value', 0...),
   ('eq', <function gte at ...>, 'gt')]]