(self, name, expr, argument_sequence=None)
Initialize a Routine instance.

        ``name``
            A string with the name of this routine in the generated code
        ``expr``
            The sympy expression that the Routine instance will represent.  If
            given a list or tuple of expressions, the routine will be
            considered to have multiple return values.
        ``argument_sequence``
            Optional list/tuple containing arguments for the routine in a
            preferred order.  If omitted, arguments will be ordered
            alphabetically, but with all input aguments first, and then output
            or in-out arguments.

        A decision about whether to use output arguments or return values,
        is made depending on the mathematical expressions.  For an expression
        of type Equality, the left hand side is made into an OutputArgument
        (or an InOutArgument if appropriate).  Else, the calculated
        expression is the return values of the routine.

        A tuple of exressions can be used to create a routine with both
        return value(s) and output argument(s).
Initialize a Routine instance.
Initialize a Routine instance .
def __init__(self, name, expr, argument_sequence=None):
        """Initialize a Routine instance.

        ``name``
            A string with the name of this routine in the generated code
        ``expr``
            The sympy expression that the Routine instance will represent.  If
            given a list or tuple of expressions, the routine will be
            considered to have multiple return values.
        ``argument_sequence``
            Optional list/tuple containing arguments for the routine in a
            preferred order.  If omitted, arguments will be ordered
            alphabetically, but with all input aguments first, and then output
            or in-out arguments.

        A decision about whether to use output arguments or return values,
        is made depending on the mathematical expressions.  For an expression
        of type Equality, the left hand side is made into an OutputArgument
        (or an InOutArgument if appropriate).  Else, the calculated
        expression is the return values of the routine.

        A tuple of exressions can be used to create a routine with both
        return value(s) and output argument(s).

        """
        arg_list = []

        if is_sequence(expr):
            if not expr:
                raise ValueError("No expression given")
            expressions = Tuple(*expr)
        else:
            expressions = Tuple(expr)

        # local variables
        local_vars = set([i.label for i in expressions.atoms(Idx)])

        # symbols that should be arguments
        symbols = expressions.free_symbols - local_vars

        # Decide whether to use output argument or return value
        return_val = []
        output_args = []
        for expr in expressions:
            if isinstance(expr, Equality):
                out_arg = expr.lhs
                expr = expr.rhs
                if isinstance(out_arg, Indexed):
                    dims = tuple([ (S.Zero, dim - 1) for dim in out_arg.shape])
                    symbol = out_arg.base.label
                elif isinstance(out_arg, Symbol):
                    dims = []
                    symbol = out_arg
                else:
                    raise CodeGenError(
                        "Only Indexed or Symbol can define output arguments")

                if expr.has(symbol):
                    output_args.append(
                        InOutArgument(symbol, out_arg, expr, dimensions=dims))
                else:
                    output_args.append(OutputArgument(
                        symbol, out_arg, expr, dimensions=dims))

                # avoid duplicate arguments
                symbols.remove(symbol)
            else:
                return_val.append(Result(expr))

        # setup input argument list
        array_symbols = {}
        for array in expressions.atoms(Indexed):
            array_symbols[array.base.label] = array

        for symbol in sorted(symbols, key=str):
            if symbol in array_symbols:
                dims = []
                array = array_symbols[symbol]
                for dim in array.shape:
                    dims.append((S.Zero, dim - 1))
                metadata = {'dimensions': dims}
            else:
                metadata = {}

            arg_list.append(InputArgument(symbol, **metadata))

        output_args.sort(key=lambda x: str(x.name))
        arg_list.extend(output_args)

        if argument_sequence is not None:
            # if the user has supplied IndexedBase instances, we'll accept that
            new_sequence = []
            for arg in argument_sequence:
                if isinstance(arg, IndexedBase):
                    new_sequence.append(arg.label)
                else:
                    new_sequence.append(arg)
            argument_sequence = new_sequence

            missing = [x for x in arg_list if x.name not in argument_sequence]
            if missing:
                raise CodeGenArgumentListError("Argument list didn't specify: %s" %
                        ", ".join([str(m.name) for m in missing]), missing)

            # create redundant arguments to produce the requested sequence
            name_arg_dict = dict([(x.name, x) for x in arg_list])
            new_args = []
            for symbol in argument_sequence:
                try:
                    new_args.append(name_arg_dict[symbol])
                except KeyError:
                    new_args.append(InputArgument(symbol))
            arg_list = new_args

        self.name = name
        self.arguments = arg_list
        self.results = return_val
        self.local_vars = local_vars
def __init__ ( self , name , expr , argument_sequence = None ) : arg_list = [ ] if is_sequence ( expr ) : if not expr : raise ValueError ( "No expression given" ) expressions = Tuple ( * expr ) else : expressions = Tuple ( expr ) # local variables local_vars = set ( [ i . label for i in expressions . atoms ( Idx ) ] ) # symbols that should be arguments symbols = expressions . free_symbols - local_vars # Decide whether to use output argument or return value return_val = [ ] output_args = [ ] for expr in expressions : if isinstance ( expr , Equality ) : out_arg = expr . lhs expr = expr . rhs if isinstance ( out_arg , Indexed ) : dims = tuple ( [ ( S . Zero , dim - 1 ) for dim in out_arg . shape ] ) symbol = out_arg . base . label elif isinstance ( out_arg , Symbol ) : dims = [ ] symbol = out_arg else : raise CodeGenError ( "Only Indexed or Symbol can define output arguments" ) if expr . has ( symbol ) : output_args . append ( InOutArgument ( symbol , out_arg , expr , dimensions = dims ) ) else : output_args . append ( OutputArgument ( symbol , out_arg , expr , dimensions = dims ) ) # avoid duplicate arguments symbols . remove ( symbol ) else : return_val . append ( Result ( expr ) ) # setup input argument list array_symbols = { } for array in expressions . atoms ( Indexed ) : array_symbols [ array . base . label ] = array for symbol in sorted ( symbols , key = str ) : if symbol in array_symbols : dims = [ ] array = array_symbols [ symbol ] for dim in array . shape : dims . append ( ( S . Zero , dim - 1 ) ) metadata = { 'dimensions' : dims } else : metadata = { } arg_list . append ( InputArgument ( symbol , * * metadata ) ) output_args . sort ( key = lambda x : str ( x . name ) ) arg_list . extend ( output_args ) if argument_sequence is not None : # if the user has supplied IndexedBase instances, we'll accept that new_sequence = [ ] for arg in argument_sequence : if isinstance ( arg , IndexedBase ) : new_sequence . append ( arg . label ) else : new_sequence . append ( arg ) argument_sequence = new_sequence missing = [ x for x in arg_list if x . name not in argument_sequence ] if missing : raise CodeGenArgumentListError ( "Argument list didn't specify: %s" % ", " . join ( [ str ( m . name ) for m in missing ] ) , missing ) # create redundant arguments to produce the requested sequence name_arg_dict = dict ( [ ( x . name , x ) for x in arg_list ] ) new_args = [ ] for symbol in argument_sequence : try : new_args . append ( name_arg_dict [ symbol ] ) except KeyError : new_args . append ( InputArgument ( symbol ) ) arg_list = new_args self . name = name self . arguments = arg_list self . results = return_val self . local_vars = local_vars