parameters: (self,expr,varorder=None,defaultsize=1)
return_statement: return dfv,varorder
docstring: Given a differentiable expression expr, return (df,varorder),
          where df is an 1-argument Python function that that takes a list of numbers or numpy array and
          outputs the derivative (Jacobian matrix) of expression expr.
          The order of variables that should be provided to df in this tuple is returned in varorder.
  
          If expr is not differentiable, then df=None is returned
  
          If vector variables are not given size hints, then they are assumed to have defaultsize.
docstring_summary: Given a differentiable expression expr, return (df,varorder),
          where df is an 1-argument Python function that that takes a list of numbers or numpy array and
          outputs the derivative (Jacobian matrix) of expression expr.
          The order of variables that should be provided to df in this tuple is returned in varorder.
docstring_tokens: Given a differentiable expression expr return ( df varorder ) where df is an 1 - argument Python function that that takes a list of numbers or numpy array and outputs the derivative ( Jacobian matrix ) of expression expr . The order of variables that should be provided to df in this tuple is returned in varorder .
function: def makeFlatFunctionDeriv(self,expr,varorder=None,defaultsize=1):
          """Given a differentiable expression expr, return (df,varorder),
          where df is an 1-argument Python function that that takes a list of numbers or numpy array and
          outputs the derivative (Jacobian matrix) of expression expr.
          The order of variables that should be provided to df in this tuple is returned in varorder.
  
          If expr is not differentiable, then df=None is returned
  
          If vector variables are not given size hints, then they are assumed to have defaultsize.
          """
          if varorder is None:
              f,varorder = self.makePyFunction(expr)
          dvs = []
          for v in varorder:
              dv = expr.deriv(v)
              if dv is None:
                  print "makeFlatFunctionDeriv: Derivative with respect to",v.name,"is undefined, returning None"
                  return None,varorder
              if not isinstance(dv,Expression):
                  if _is_exactly(dv,0) and not v.type.is_scalar():
                      #get the jacobian dimensions right
                      assert v.type.char == 'V',"Can't make flat function of non-numeric or non-vector types: "+str(v.type)
                      dv = zero(count.optimized(v))
                  else:
                      dv = ConstantExpression(dv)
              dvs.append(dv)
          if len(dvs) > 1:
              rt = expr.returnType()
              if rt is None or rt.char is None:
                  print "makeFlatFunctionDeriv: no return type inferred, assuming vector"
                  rt = Type('V')
              if rt.is_scalar():
                  dflist,varorder = self.makePyFunction(flatten(*dvs),varorder)
                  df = lambda *args: np.array(dflist(*args))
              elif rt.char == 'V':
                  df,varorder = self.makePyFunction(column_stack(*dvs),varorder)
              else:
                  print "Expression",expr,"has return type",rt
                  raise NotImplementedError("Can't make flat function of non-numeric or non-vector types: "+str(rt))
          else:
              df,varorder = self.makePyFunction(dvs[0],varorder)
          indices = self.getFlatVarRanges(varorder,defaultsize)
          def dfv(x):
              arglist = []
              for i,v in enumerate(varorder):
                  if v.type.char in 'AM':
                      arglist.append(x[indices[i]:indices[i+1]].reshape(v.size))
                  elif v.type.char == 'V':
                      arglist.append(x[indices[i]:indices[i+1]])
                  else:
                      arglist.append(x[indices[i]])
              #print "Extracted arguments",arglist
              return df(*arglist)
          return dfv,varorder
function_tokens: def makeFlatFunctionDeriv ( self , expr , varorder = None , defaultsize = 1 ) : if varorder is None : f , varorder = self . makePyFunction ( expr ) dvs = [ ] for v in varorder : dv = expr . deriv ( v ) if dv is None : print "makeFlatFunctionDeriv: Derivative with respect to" , v . name , "is undefined, returning None" return None , varorder if not isinstance ( dv , Expression ) : if _is_exactly ( dv , 0 ) and not v . type . is_scalar ( ) : #get the jacobian dimensions right assert v . type . char == 'V' , "Can't make flat function of non-numeric or non-vector types: " + str ( v . type ) dv = zero ( count . optimized ( v ) ) else : dv = ConstantExpression ( dv ) dvs . append ( dv ) if len ( dvs ) > 1 : rt = expr . returnType ( ) if rt is None or rt . char is None : print "makeFlatFunctionDeriv: no return type inferred, assuming vector" rt = Type ( 'V' ) if rt . is_scalar ( ) : dflist , varorder = self . makePyFunction ( flatten ( * dvs ) , varorder ) df = lambda * args : np . array ( dflist ( * args ) ) elif rt . char == 'V' : df , varorder = self . makePyFunction ( column_stack ( * dvs ) , varorder ) else : print "Expression" , expr , "has return type" , rt raise NotImplementedError ( "Can't make flat function of non-numeric or non-vector types: " + str ( rt ) ) else : df , varorder = self . makePyFunction ( dvs [ 0 ] , varorder ) indices = self . getFlatVarRanges ( varorder , defaultsize ) def dfv ( x ) : arglist = [ ] for i , v in enumerate ( varorder ) : if v . type . char in 'AM' : arglist . append ( x [ indices [ i ] : indices [ i + 1 ] ] . reshape ( v . size ) ) elif v . type . char == 'V' : arglist . append ( x [ indices [ i ] : indices [ i + 1 ] ] ) else : arglist . append ( x [ indices [ i ] ] ) #print "Extracted arguments",arglist return df ( * arglist ) return dfv , varorder