Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | Static Private Attributes | List of all members
CellMLToNektar.optimize.LookupTableAnalyser Class Reference
Inheritance diagram for CellMLToNektar.optimize.LookupTableAnalyser:
Inheritance graph
[legend]
Collaboration diagram for CellMLToNektar.optimize.LookupTableAnalyser:
Collaboration graph
[legend]

Classes

class  LUTState
 

Public Member Functions

def __init__
 
def config
 
def var_is_membrane_potential
 
def is_allowed_variable
 
def is_keying_var
 
def set_params
 
def get_param
 
def create_state_from_annotations
 
def analyse_for_lut
 
def check_divide_by_table
 
def check_commutative_tables
 
def annotate_as_suitable
 
def remove_lut_annotations
 
def analyse_model
 
def calculate_dependencies
 

Static Public Member Functions

def copy_lut_annotations
 

Public Attributes

 doc
 
 solver_info
 
 annotate_failures
 
 annotate_outermost_only
 

Static Public Attributes

tuple lut_expensive_funcs
 

Private Member Functions

def _find_tables
 
def _determine_unneeded_tables
 
def _determine_duplicate_tables
 

Static Private Attributes

dictionary _LT_DEFAULTS
 

Detailed Description

Analyses & annotates a CellML model to indicate where lookup
tables can be used.

Definition at line 384 of file optimize.py.

Constructor & Destructor Documentation

def CellMLToNektar.optimize.LookupTableAnalyser.__init__ (   self)
Create an analyser.

Definition at line 390 of file optimize.py.

391  def __init__(self):
392  """Create an analyser."""
393  # No model to analyse yet
394  self.doc = None
395  # Set default parameter values
396  self.set_params()

Member Function Documentation

def CellMLToNektar.optimize.LookupTableAnalyser._determine_duplicate_tables (   self)
private
Determine whether we have multiple tables for the same expression.

Any expression that is identical to a previous table will be re-annotated to refer to the
previous table, instead of declaring a new one.

This is a temporary measure until we have proper sub-expression elimination for the Jacobian
and residual calculations.

Definition at line 860 of file optimize.py.

861  def _determine_duplicate_tables(self):
862  """Determine whether we have multiple tables for the same expression.
863 
864  Any expression that is identical to a previous table will be re-annotated to refer to the
865  previous table, instead of declaring a new one.
866 
867  This is a temporary measure until we have proper sub-expression elimination for the Jacobian
868  and residual calculations.
869  """
870  uniq_tables = []
871  for expr in self.doc.lookup_tables:
872  for table in uniq_tables:
873  if expr.same_tree(table):
874  lt_name = table.getAttributeNS(NSS['lut'], u'table_name', u'')
875  # Need to remove old name before we can set a new one (grr amara)
876  del expr.table_name
877  expr.xml_set_attribute((u'lut:table_name', NSS['lut']), lt_name)
878  break
879  else:
880  uniq_tables.append(expr)
def CellMLToNektar.optimize.LookupTableAnalyser._determine_unneeded_tables (   self)
private
Determine whether some expressions identified as lookup tables aren't actually used.

This occurs if some ODEs have been linearised, in which case the original definitions
will have been analysed for lookup tables, but aren't actually used.

TODO: The original definitions might be used for computing derived quantities...

Definition at line 834 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser._find_tables(), CellMLToNektar.utilities.DEBUG(), and CellMLToNektar.optimize.LookupTableAnalyser.remove_lut_annotations().

835  def _determine_unneeded_tables(self):
836  """Determine whether some expressions identified as lookup tables aren't actually used.
837 
838  This occurs if some ODEs have been linearised, in which case the original definitions
839  will have been analysed for lookup tables, but aren't actually used.
840 
841  TODO: The original definitions might be used for computing derived quantities...
842  """
843  original_tables = {}
844  new_tables = {}
845  def f(exprs, table_dict):
846  exprs = filter(lambda n: isinstance(n, (mathml_ci, mathml_apply, mathml_piecewise)), exprs)
847  for node in self.doc.model.calculate_extended_dependencies(exprs):
848  if isinstance(node, mathml_apply):
849  self._find_tables(node, table_dict)
850  for u, t, eqns in self.solver_info.get_linearised_odes():
851  original_defn = u.get_ode_dependency(t)
852  f([original_defn], original_tables)
853  f(eqns, new_tables)
854  for id_ in set(original_tables.keys()) - set(new_tables.keys()):
855  expr = original_tables[id_]
856  self.remove_lut_annotations(expr)
857  expr.xml_set_attribute((u'lut:reason', NSS['lut']),
858  u'Expression will not be used in generated code.')
859  DEBUG('lookup-tables', 'Not annotating probably unused expression', expr)
def CellMLToNektar.optimize.LookupTableAnalyser._find_tables (   self,
  expr,
  table_dict 
)
private
Helper method for _determine_unneeded_tables.

Definition at line 826 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser._find_tables().

Referenced by CellMLToNektar.optimize.LookupTableAnalyser._determine_unneeded_tables(), and CellMLToNektar.optimize.LookupTableAnalyser._find_tables().

827  def _find_tables(self, expr, table_dict):
828  """Helper method for _determine_unneeded_tables."""
829  if expr.getAttributeNS(NSS['lut'], u'possible', '') == u'yes':
830  table_dict[id(expr)] = expr
831  else:
832  for e in self.doc.model.xml_element_children(expr):
833  self._find_tables(e, table_dict)
def CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut (   self,
  expr,
  var_checker_fn 
)
Check if the given expression can be replaced by a lookup table.

The first argument is the expression to check; the second is a
function which takes a variable object and returns True iff this
variable is permitted within a lookup table expression.

If self.annotate_failures is True then annotate <apply> and
<piecewise> expressions which don't qualify with the reason
why they do not.
This can be:
 'no_var' - doesn't contain the table variable
 'bad_var <vname>' - contains a variable which isn't permitted
 'no_func' - doesn't contain an expensive function
or a comma separated combination of the above.
The annotation is stored as the lut:reason attribute.

If self.annotate_outermost_only is True then only annotate the
outermost qualifying expression, rather than also annotating
qualifying subexpressions.

Definition at line 556 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut(), CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable(), CellMLToNektar.optimize.LookupTableAnalyser.annotate_failures, CellMLToNektar.optimize.LookupTableAnalyser.check_commutative_tables(), CellMLToNektar.optimize.LookupTableAnalyser.check_divide_by_table(), CellMLToNektar.pycml.child_i(), CellMLToNektar.optimize.LookupTableAnalyser.config(), CellMLToNektar.optimize.LookupTableAnalyser.create_state_from_annotations(), CellMLToNektar.utilities.DEBUG(), CellMLToNektar.optimize.LookupTableAnalyser.is_keying_var(), and CellMLToNektar.optimize.LookupTableAnalyser.lut_expensive_funcs.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

557  def analyse_for_lut(self, expr, var_checker_fn):
558  """Check if the given expression can be replaced by a lookup table.
559 
560  The first argument is the expression to check; the second is a
561  function which takes a variable object and returns True iff this
562  variable is permitted within a lookup table expression.
563 
564  If self.annotate_failures is True then annotate <apply> and
565  <piecewise> expressions which don't qualify with the reason
566  why they do not.
567  This can be:
568  'no_var' - doesn't contain the table variable
569  'bad_var <vname>' - contains a variable which isn't permitted
570  'no_func' - doesn't contain an expensive function
571  or a comma separated combination of the above.
572  The annotation is stored as the lut:reason attribute.
573 
574  If self.annotate_outermost_only is True then only annotate the
575  outermost qualifying expression, rather than also annotating
576  qualifying subexpressions.
577  """
578  # If this is a cloned expression, then just copy any annotations on the original.
579  if isinstance(expr, mathml):
580  source_expr = expr.get_original_of_clone()
581  else:
582  source_expr = None
583  if source_expr and source_expr.getAttributeNS(NSS['lut'], u'possible', '') != '':
584  LookupTableAnalyser.copy_lut_annotations(source_expr, expr)
585  state = self.create_state_from_annotations(source_expr)
586  DEBUG('lookup-tables', "No need to analyse clone", expr.xml(), state.suitable(), state.reason())
587  else:
588  # Initialise the indicators
589  state = self.LUTState()
590  # Process current node
591  if isinstance(expr, mathml_ci):
592  # Variable reference
593  if var_checker_fn(expr.variable):
594  # Could be a permitted var that isn't a keying var
595  if self.is_keying_var(expr.variable):
596  assert state.table_var is None # Sanity check
597  state.has_var = True
598  state.table_var = expr.variable
599  else:
600  state.bad_vars.add(expr.variable.name)
601  elif isinstance(expr, mathml_piecewise):
602  # Recurse into pieces & otherwise options
603  if hasattr(expr, u'otherwise'):
604  r = self.analyse_for_lut(child_i(expr.otherwise, 1),
605  var_checker_fn)
606  state.update(r)
607  for piece in getattr(expr, u'piece', []):
608  r = self.analyse_for_lut(child_i(piece, 1), var_checker_fn)
609  state.update(r)
610  r = self.analyse_for_lut(child_i(piece, 2), var_checker_fn)
611  state.update(r)
612  elif isinstance(expr, mathml_apply):
613  # Check function
614  if (not state.has_func and
615  expr.operator().localName in self.lut_expensive_funcs):
616  state.has_func = True
617  # Check operands
618  operand_states = {}
619  for operand in expr.operands():
620  r = self.analyse_for_lut(operand, var_checker_fn)
621  state.update(r)
622  operand_states[id(operand)] = r
623  # Check qualifiers
624  for qual in expr.qualifiers():
625  r = self.analyse_for_lut(qual, var_checker_fn)
626  state.update(r)
627  # Special case additional optimisations
628  if self.config and self.config.options.combine_commutative_tables and not state.suitable():
629  if isinstance(expr.operator(), reduce_commutative_nary):
630  self.check_commutative_tables(expr, operand_states)
631  elif isinstance(expr.operator(), mathml_divide):
632  self.check_divide_by_table(expr, operand_states)
633  else:
634  # Just recurse into children
635  for e in expr.xml_children:
636  if getattr(e, 'nodeType', None) == Node.ELEMENT_NODE:
637  r = self.analyse_for_lut(e, var_checker_fn)
638  state.update(r)
639  # Annotate the expression if appropriate
640  if isinstance(expr, (mathml_apply, mathml_piecewise)):
641  if state.suitable():
642  self.annotate_as_suitable(expr, state.table_var)
643  else:
644  if self.annotate_failures:
645  expr.xml_set_attribute((u'lut:reason', NSS['lut']), state.reason())
646  return state
def CellMLToNektar.optimize.LookupTableAnalyser.analyse_model (   self,
  doc,
  solver_info,
  annotate_failures = True,
  annotate_outermost_only = True 
)
Analyse the given document.

This method checks all expressions (and subexpressions)
in the given document for whether they could be converted to
use a lookup table, and annotates them appropriately.

By default expressions which don't qualify will be annotated
to indicate why; set annotate_failures to False to suppress
this.

Also by default only the outermost suitable expression in any
given tree will be annotated; if you want to annotate suitable
subexpressions of a suitable expression then pass
annotate_outermost_only as False.

Definition at line 760 of file optimize.py.

References Nektar::LibUtilities::H5DataSource.doc, CellMLToNektar.optimize.PartialEvaluator.doc, and CellMLToNektar.optimize.LookupTableAnalyser.doc.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.remove_lut_annotations().

761  annotate_outermost_only=True):
762  """Analyse the given document.
763 
764  This method checks all expressions (and subexpressions)
765  in the given document for whether they could be converted to
766  use a lookup table, and annotates them appropriately.
767 
768  By default expressions which don't qualify will be annotated
769  to indicate why; set annotate_failures to False to suppress
770  this.
771 
772  Also by default only the outermost suitable expression in any
773  given tree will be annotated; if you want to annotate suitable
774  subexpressions of a suitable expression then pass
775  annotate_outermost_only as False.
776  """
777  self.doc = doc
778  self.solver_info = solver_info
779  self.annotate_failures = annotate_failures
780  self.annotate_outermost_only = annotate_outermost_only
781  doc.lookup_tables = {}
782  # How to check for allowed variables
783  if hasattr(doc, '_cml_config'):
784  checker_fn = self.is_allowed_variable
785  else:
786  checker_fn = self.var_is_membrane_potential
787 
788  # Check all expressions
789  for expr in (e for e in doc.model.get_assignments()
790  if isinstance(e, mathml_apply)):
791  ops = expr.operands()
792  ops.next()
793  e = ops.next()
794  self.analyse_for_lut(e, checker_fn)
795  for expr in solver_info.get_modifiable_mathematics():
796  self.analyse_for_lut(expr, checker_fn)
797 
798  if solver_info.has_modifiable_mathematics():
800 
801  # Assign names (numbers) to the lookup tables found.
802  # Also work out which ones can share index variables into the table.
803  doc.lookup_tables = doc.lookup_tables.keys()
804  doc.lookup_tables.sort(cmp=element_path_cmp)
805  doc.lookup_table_indexes, n = {}, 0
806  for i, expr in enumerate(doc.lookup_tables):
807  expr.xml_set_attribute((u'lut:table_name', NSS['lut']), unicode(i))
808  comp = expr.get_component()
809  var = comp.get_variable_by_name(expr.var).get_source_variable(recurse=True)
810  key = (expr.min, expr.max, expr.step, var)
811  if not key in doc.lookup_table_indexes:
812  doc.lookup_table_indexes[key] = unicode(n)
813  n += 1
814  expr.xml_set_attribute((u'lut:table_index', NSS['lut']), doc.lookup_table_indexes[key])
815 
816  if solver_info.has_modifiable_mathematics():
818 
819  # Re-do dependency analysis so that an expression using lookup
820  # tables only depends on the keying variable.
821  for expr in (e for e in doc.model.get_assignments()
822  if isinstance(e, mathml_apply)):
823  expr.classify_variables(root=True,
824  dependencies_only=True,
825  needs_special_treatment=self.calculate_dependencies)
def CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable (   self,
  expr,
  table_var 
)
Annotate the given expression as being suitable for a lookup table.

Definition at line 714 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser.annotate_outermost_only, CellMLToNektar.optimize.LookupTableAnalyser.get_param(), and CellMLToNektar.optimize.LookupTableAnalyser.remove_lut_annotations().

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut(), CellMLToNektar.optimize.LookupTableAnalyser.check_commutative_tables(), and CellMLToNektar.optimize.LookupTableAnalyser.check_divide_by_table().

715  def annotate_as_suitable(self, expr, table_var):
716  """Annotate the given expression as being suitable for a lookup table."""
717  if self.annotate_outermost_only:
718  # Remove annotations from (expr and) child expressions
719  self.remove_lut_annotations(expr)
720  for param in ['min', 'max', 'step']:
721  expr.xml_set_attribute((u'lut:' + param, NSS['lut']),
722  self.get_param('table_' + param, table_var))
723  expr.xml_set_attribute((u'lut:var', NSS['lut']), table_var.name)
724  expr.xml_set_attribute((u'lut:possible', NSS['lut']), u'yes')
725  self.doc.lookup_tables[expr] = True
def CellMLToNektar.optimize.LookupTableAnalyser.calculate_dependencies (   self,
  expr 
)
Determine the dependencies of an expression that might use a lookup table.

This method is suitable for use as the needs_special_treatment function in
mathml_apply.classify_variables.  It is used to override the default recursion
into sub-trees.  It takes a single sub-tree as argument, and returns either
the dependency set for that sub-tree, or None to use the default recursion.

Expressions that can use a lookup table only depend on the keying variable.

Definition at line 881 of file optimize.py.

882  def calculate_dependencies(self, expr):
883  """Determine the dependencies of an expression that might use a lookup table.
884 
885  This method is suitable for use as the needs_special_treatment function in
886  mathml_apply.classify_variables. It is used to override the default recursion
887  into sub-trees. It takes a single sub-tree as argument, and returns either
888  the dependency set for that sub-tree, or None to use the default recursion.
889 
890  Expressions that can use a lookup table only depend on the keying variable.
891  """
892  if expr.getAttributeNS(NSS['lut'], u'possible', '') == u'yes':
893  key_var_name = expr.getAttributeNS(NSS['lut'], u'var')
894  key_var = expr.component.get_variable_by_name(key_var_name).get_source_variable(recurse=True)
895  return set([key_var])
896  # If not a table, use default behaviour
897  return None
898 
def CellMLToNektar.optimize.LookupTableAnalyser.check_commutative_tables (   self,
  expr,
  operand_states 
)
Check whether we can combine suitable operands into a new expression.

If expr has a commutative (and associative) n-ary operator, but is not suitable as a
whole to become a lookup table (checked by caller) then we might still be able to
do slightly better than just analysing its operands.  If multiple operands can be
replaced by tables keyed on the same variable, these can be combined into a new
application of the same operator as expr, which can then be replaced as a whole
by a single lookup table, and made an operand of expr.

Alternatively, if at least one operand can be replaced by a table, and a subset of
other operands do not contain other variables, then they can be included in the single
table.

Definition at line 664 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable().

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

665  def check_commutative_tables(self, expr, operand_states):
666  """Check whether we can combine suitable operands into a new expression.
667 
668  If expr has a commutative (and associative) n-ary operator, but is not suitable as a
669  whole to become a lookup table (checked by caller) then we might still be able to
670  do slightly better than just analysing its operands. If multiple operands can be
671  replaced by tables keyed on the same variable, these can be combined into a new
672  application of the same operator as expr, which can then be replaced as a whole
673  by a single lookup table, and made an operand of expr.
674 
675  Alternatively, if at least one operand can be replaced by a table, and a subset of
676  other operands do not contain other variables, then they can be included in the single
677  table.
678  """
679  # Operands that can be replaced by tables
680  table_operands = filter(lambda op: operand_states[id(op)].suitable(), expr.operands())
681  if not table_operands:
682  return
683  # Sort these suitable operands by table_var (map var id to var & operand list, respectively)
684  table_vars, table_var_operands = {}, {}
685  for oper in table_operands:
686  table_var = operand_states[id(oper)].table_var
687  table_var_id = id(table_var)
688  if not table_var_id in table_vars:
689  table_vars[table_var_id] = table_var
690  table_var_operands[table_var_id] = []
691  table_var_operands[table_var_id].append(oper)
692  # Figure out if any operands aren't suitable by themselves but could be included in a table
693  potential_operands = {id(None): []}
694  for table_var_id in table_vars.keys():
695  potential_operands[table_var_id] = []
696  for op in expr.operands():
697  state = operand_states[id(op)]
698  if not state.suitable() and not state.bad_vars:
699  if not state.table_var in potential_operands:
700  potential_operands[id(state.table_var)] = []
701  potential_operands[id(state.table_var)].append(op)
702  # Do any combining
703  for table_var_id in table_vars.keys():
704  suitable_opers = table_var_operands[table_var_id] + potential_operands[table_var_id] + potential_operands[id(None)]
705  if len(suitable_opers) > 1:
706  # Create new sub-expression with the suitable operands
707  for oper in suitable_opers:
708  expr.safe_remove_child(oper)
709  new_expr = mathml_apply.create_new(expr, expr.operator().localName, suitable_opers)
710  expr.xml_append(new_expr)
711  self.annotate_as_suitable(new_expr, table_vars[table_var_id])
712  # Remove the operands with no table_var from consideration with other keying vars
713  potential_operands[id(None)] = []
def CellMLToNektar.optimize.LookupTableAnalyser.check_divide_by_table (   self,
  expr,
  operand_states 
)
Convert division by a table into multiplication.

This is called if expr, a division, cannot be replaced as a whole by a lookup table.
If the denominator can be replaced by a table, then convert expr into a multiplication
by the reciprocal, moving the division into the table.

Definition at line 647 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable().

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

648  def check_divide_by_table(self, expr, operand_states):
649  """Convert division by a table into multiplication.
650 
651  This is called if expr, a division, cannot be replaced as a whole by a lookup table.
652  If the denominator can be replaced by a table, then convert expr into a multiplication
653  by the reciprocal, moving the division into the table.
654  """
655  numer, denom = list(expr.operands())
656  state = operand_states[id(denom)]
657  if state.suitable():
658  expr.safe_remove_child(numer)
659  expr.safe_remove_child(denom)
660  recip = mathml_apply.create_new(expr, u'divide', [(u'1', u'dimensionless'), denom])
661  times = mathml_apply.create_new(expr, u'times', [numer, recip])
662  expr.replace_child(expr, times, expr.xml_parent)
663  self.annotate_as_suitable(recip, state.table_var)
def CellMLToNektar.optimize.LookupTableAnalyser.config (   self)
Get the current document's configuration store.

Definition at line 398 of file optimize.py.

References Nektar::LibUtilities::H5DataSource.doc, CellMLToNektar.optimize.PartialEvaluator.doc, and CellMLToNektar.optimize.LookupTableAnalyser.doc.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut(), and CellMLToNektar.optimize.LookupTableAnalyser.is_keying_var().

399  def config(self):
400  """Get the current document's configuration store."""
401  return getattr(self.doc, '_cml_config', None)
def CellMLToNektar.optimize.LookupTableAnalyser.copy_lut_annotations (   from_expr,
  to_expr 
)
static
Copy any lookup table annotations from one expression to another.

Definition at line 727 of file optimize.py.

728  def copy_lut_annotations(from_expr, to_expr):
729  """Copy any lookup table annotations from one expression to another."""
730  for pyname, fullname in from_expr.xml_attributes.iteritems():
731  if fullname[1] == NSS['lut']:
732  to_expr.xml_set_attribute(fullname, getattr(from_expr, pyname))
def CellMLToNektar.optimize.LookupTableAnalyser.create_state_from_annotations (   self,
  expr 
)
Create a LUTState instance from an already annotated expression.

Definition at line 537 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

538  def create_state_from_annotations(self, expr):
539  """Create a LUTState instance from an already annotated expression."""
540  state = self.LUTState()
541  possible = expr.getAttributeNS(NSS['lut'], u'possible', '')
542  if possible == u'yes':
543  varname = expr.getAttributeNS(NSS['lut'], u'var')
544  state.table_var = expr.component.get_variable_by_name(varname)
545  elif possible == u'no':
546  reason = expr.getAttributeNS(NSS['lut'], u'reason', '')
547  reasons = reason.split(u',')
548  for reason in reasons:
549  if reason == u'no_var':
550  state.has_var = False
551  elif reason == u'no_func':
552  state.has_func = False
553  elif reason.startswith(u'bad_var '):
554  state.bad_vars.add(reason[8:])
555  return state
def CellMLToNektar.optimize.LookupTableAnalyser.get_param (   self,
  param_name,
  table_var 
)
Get the value of the lookup table parameter.

table_var is the variable object being used to key this table.

If the document has a config store, lookup the value there.
If that doesn't give us a value, use that given using set_params.

Definition at line 453 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable().

454  def get_param(self, param_name, table_var):
455  """Get the value of the lookup table parameter.
456 
457  table_var is the variable object being used to key this table.
458 
459  If the document has a config store, lookup the value there.
460  If that doesn't give us a value, use that given using set_params.
461  """
462  try:
463  val = self.config.lut_config[
464  table_var.get_source_variable(recurse=True)][param_name]
465  except AttributeError, KeyError:
466  val = getattr(self, param_name)
467  return val
def CellMLToNektar.optimize.LookupTableAnalyser.is_allowed_variable (   self,
  var 
)
Return True iff the given variable is allowed in a lookup table.

This method uses the config store in the document to check the variable object.

Definition at line 410 of file optimize.py.

411  def is_allowed_variable(self, var):
412  """Return True iff the given variable is allowed in a lookup table.
413 
414  This method uses the config store in the document to check the variable object.
415  """
416  var = var.get_source_variable(recurse=True)
417  allowed = (var in self.config.lut_config or
418  (self.config.options.include_dt_in_tables and
419  var is self.solver_info.get_dt().get_source_variable(recurse=True)))
420  return allowed
def CellMLToNektar.optimize.LookupTableAnalyser.is_keying_var (   self,
  var 
)
Return True iff the given variable can be used as a table key.

Will check the config store if it exists.  If not, the variable name must match self.table_var.

Definition at line 421 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser.config(), and CellMLToNektar.optimize.LookupTableAnalyser.LUTState.table_var.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

422  def is_keying_var(self, var):
423  """Return True iff the given variable can be used as a table key.
424 
425  Will check the config store if it exists. If not, the variable name must match self.table_var.
426  """
427  if self.config:
428  return var.get_source_variable(recurse=True) in self.config.lut_config
429  else:
430  return var.name == self.table_var
def CellMLToNektar.optimize.LookupTableAnalyser.remove_lut_annotations (   self,
  expr,
  remove_reason = False 
)
Remove lookup table annotations from the given expression.

By default this will only remove annotations from expressions
(and sub-expressions) that can be converted to use lookup tables.
If remove_reason is True, then the lut:reason attributes on
non-qualifying expressions will also be removed.

Definition at line 733 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser.analyse_model(), and CellMLToNektar.optimize.LookupTableAnalyser.remove_lut_annotations().

Referenced by CellMLToNektar.optimize.LookupTableAnalyser._determine_unneeded_tables(), CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable(), and CellMLToNektar.optimize.LookupTableAnalyser.remove_lut_annotations().

734  def remove_lut_annotations(self, expr, remove_reason=False):
735  """Remove lookup table annotations from the given expression.
736 
737  By default this will only remove annotations from expressions
738  (and sub-expressions) that can be converted to use lookup tables.
739  If remove_reason is True, then the lut:reason attributes on
740  non-qualifying expressions will also be removed.
741  """
742  # Remove from this expression
743  delete_table = False
744  for pyname in getattr(expr, 'xml_attributes', {}).keys():
745  fullname = expr.xml_attributes[pyname]
746  if fullname[1] == NSS['lut']:
747  if remove_reason or fullname[0] != u'lut:reason':
748  expr.__delattr__(pyname)
749  if fullname[0] != u'lut:reason':
750  delete_table = True
751  # Delete expr from list of lookup tables?
752  if delete_table:
753  del self.doc.lookup_tables[expr]
754  # Recurse into children
755  for e in expr.xml_children:
756  if getattr(e, 'nodeType', None) == Node.ELEMENT_NODE:
757  self.remove_lut_annotations(e, remove_reason)
def CellMLToNektar.optimize.LookupTableAnalyser.set_params (   self,
  kw 
)
Set parameters controlling lookup table generation.

Keyword parameters control the lookup table settings, which are
stored as attributes on suitable expressions.
table_min - minimum table entry (unicode) -> lut:min
table_max - maximum table entry (unicode) -> lut:max
table_step - table step size (unicode) -> lut:step
table_var - the name of the variable indexing the table (unicode) -> lut:var

Definition at line 435 of file optimize.py.

References CellMLToNektar.optimize.LookupTableAnalyser._LT_DEFAULTS.

436  def set_params(self, **kw):
437  """Set parameters controlling lookup table generation.
438 
439  Keyword parameters control the lookup table settings, which are
440  stored as attributes on suitable expressions.
441  table_min - minimum table entry (unicode) -> lut:min
442  table_max - maximum table entry (unicode) -> lut:max
443  table_step - table step size (unicode) -> lut:step
444  table_var - the name of the variable indexing the table (unicode) -> lut:var
445  """
446  defaults = self._LT_DEFAULTS
447  for attr in defaults:
448  if attr in kw:
449  setattr(self, attr, kw[attr])
450  else:
451  setattr(self, attr, getattr(self, attr, defaults[attr]))
452  return
def CellMLToNektar.optimize.LookupTableAnalyser.var_is_membrane_potential (   self,
  var 
)
Determine if the given variable represents the transmembrane potential.

This method takes an instance of cellml_variable and returns a boolean.

Definition at line 402 of file optimize.py.

403  def var_is_membrane_potential(self, var):
404  """Determine if the given variable represents the transmembrane potential.
405 
406  This method takes an instance of cellml_variable and returns a boolean.
407  """
408  return (var.name in [u'V', u'membrane__V'] and
409  var.get_type(follow_maps=True) == VarTypes.State)

Member Data Documentation

dictionary CellMLToNektar.optimize.LookupTableAnalyser._LT_DEFAULTS
staticprivate
Initial value:
1 = {'table_min': u'-100.0001',
2  'table_max': u'49.9999',
3  'table_step': u'0.01',
4  'table_var': u'V'}

Definition at line 431 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.set_params().

CellMLToNektar.optimize.LookupTableAnalyser.annotate_failures

Definition at line 778 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

CellMLToNektar.optimize.LookupTableAnalyser.annotate_outermost_only

Definition at line 779 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.annotate_as_suitable().

CellMLToNektar.optimize.LookupTableAnalyser.doc

Definition at line 393 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_model(), CellMLToNektar.translators.CellMLTranslator.config(), CellMLToNektar.optimize.LookupTableAnalyser.config(), and CellMLToNektar.translators.CellMLTranslator.scan_for_lookup_tables().

tuple CellMLToNektar.optimize.LookupTableAnalyser.lut_expensive_funcs
static
Initial value:
1 = frozenset(('exp', 'log', 'ln', 'root',
2  'sin', 'cos', 'tan',
3  'sec', 'csc', 'cot',
4  'sinh', 'cosh', 'tanh',
5  'sech', 'csch', 'coth',
6  'arcsin', 'arccos', 'arctan',
7  'arcsinh', 'arccosh', 'arctanh',
8  'arcsec', 'arccsc', 'arccot',
9  'arcsech', 'arccsch', 'arccoth'))

Definition at line 469 of file optimize.py.

Referenced by CellMLToNektar.optimize.LookupTableAnalyser.analyse_for_lut().

CellMLToNektar.optimize.LookupTableAnalyser.solver_info

Definition at line 777 of file optimize.py.