class_docstr: FunctionGraph Feature to track matrix properties.
  
  This is a similar feature to variable 'tags'. In fact, tags are one way
  to provide hints.
  
  This class exists because tags were not documented well, and the
  semantics of how tag information should be moved around during
  optimizations was never clearly spelled out.
  
  Hints are assumptions about mathematical properties of variables.
  If one variable is substituted for another by an optimization,
  then it means that the assumptions should be transferred to the
  new variable.
  
  Hints are attached to 'positions in a graph' rather than to variables
  in particular, although Hints are originally attached to a particular
  positition in a graph *via* a variable in that original graph.
  
  Examples of hints are:
  - shape information
  - matrix properties (e.g. symmetry, psd, banded, diagonal)
  
  Hint information is propagated through the graph similarly to graph
  optimizations, except that adding a hint does not change the graph.
  Adding a hint is not something that debugmode will check.
  
  #TODO: should a Hint be an object that can actually evaluate its
  #      truthfulness?
  #      Should the PSD property be an object that can check the
  #      PSD-ness of a variable?
class_docstr_tok: ["FunctionGraph","Feature","to","track","matrix","properties",".","This","is","a","similar","feature","to","variable","'tags","'",".","In","fact",",","tags","are","one","way","to","provide","hints",".","This","class","exists","because","tags","were","not","documented","well",",","and","the","semantics","of","how","tag","information","should","be","moved","around","during","optimizations","was","never","clearly","spelled","out",".","Hints","are","assumptions","about","mathematical","properties","of","variables",".","If","one","variable","is","substituted","for","another","by","an","optimization",",","then","it","means","that","the","assumptions","should","be","transferred","to","the","new","variable",".","Hints","are","attached","to","'positions","in","a","graph","'","rather","than","to","variables","in","particular",",","although","Hints","are","originally","attached","to","a","particular","positition","in","a","graph","*","via","*","a","variable","in","that","original","graph",".","Examples","of","hints","are",":","-","shape","information","-","matrix","properties","(","e.g",".","symmetry",",","psd",",","banded",",","diagonal",")","Hint","information","is","propagated","through","the","graph","similarly","to","graph","optimizations",",","except","that","adding","a","hint","does","not","change","the","graph",".","Adding","a","hint","is","not","something","that","debugmode","will","check",".","#","TODO",":","should","a","Hint","be","an","object","that","can","actually","evaluate","its","#","truthfulness","?","#","Should","the","PSD","property","be","an","object","that","can","check","the","#","PSD-ness","of","a","variable","?"]
code: def update_second_from_first(self, r0, r1):
      old_hints = self.hints[r0]
      new_hints = self.hints[r1]
      for k, v in iteritems(old_hints):
          if k in new_hints and new_hints[k] is not v:
              raise NotImplementedError()
          if k not in new_hints:
              new_hints[k] = v
  
imports: from __future__ import absolute_import, print_function, division
  import logging
  from six import iteritems, integer_types
  from six.moves import xrange
  from theano.gof import Op, Apply
  from theano.tensor import DimShuffle, Dot
  from theano.tensor.blas import Dot22
  from theano import tensor
  import theano.tensor
  from theano.tensor.opt import register_stabilize, register_specialize, register_canonicalize
  from theano.gof import local_optimizer
  from theano.gof.opt import Optimizer
  from theano.tensor.nlinalg import MatrixInverse, matrix_inverse, extract_diag, trace, det
  from theano.tensor.slinalg import Cholesky, cholesky, Solve, solve, imported_scipy
label_desc: Use image node_id 5 for calling the HintsFeature obj's underlying member method code with example usage: obj.update_second_from_first(r0, r1) without return types