(operands: Any)
return input_subscripts, output_subscript, operands
A reproduction of einsum c side einsum parsing in python.

    Returns
    -------
    input_strings : str
        Parsed input strings
    output_string : str
        Parsed output string
    operands : list of array_like
        The operands to use in the numpy contraction

    Examples
    --------
    The operand list is simplified to reduce printing:

    >>> a = np.random.rand(4, 4)
    >>> b = np.random.rand(4, 4, 4)
    >>> parse_einsum_input(('...a,...a->...', a, b))
    ('za,xza', 'xz', [a, b])

    >>> parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0]))
    ('za,xza', 'xz', [a, b])
A reproduction of einsum c side einsum parsing in python.
A reproduction of einsum c side einsum parsing in python .
def parse_einsum_input(operands: Any) -> Tuple[str, str, List[ArrayType]]:
    """
    A reproduction of einsum c side einsum parsing in python.

    Returns
    -------
    input_strings : str
        Parsed input strings
    output_string : str
        Parsed output string
    operands : list of array_like
        The operands to use in the numpy contraction

    Examples
    --------
    The operand list is simplified to reduce printing:

    >>> a = np.random.rand(4, 4)
    >>> b = np.random.rand(4, 4, 4)
    >>> parse_einsum_input(('...a,...a->...', a, b))
    ('za,xza', 'xz', [a, b])

    >>> parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0]))
    ('za,xza', 'xz', [a, b])
    """

    if len(operands) == 0:
        raise ValueError("No input operands")

    if isinstance(operands[0], str):
        subscripts = operands[0].replace(" ", "")
        operands = [possibly_convert_to_numpy(x) for x in operands[1:]]

    else:
        subscripts, operands = convert_interleaved_input(operands)

    # Check for proper "->"
    if ("-" in subscripts) or (">" in subscripts):
        invalid = (subscripts.count("-") > 1) or (subscripts.count(">") > 1)
        if invalid or (subscripts.count("->") != 1):
            raise ValueError("Subscripts can only contain one '->'.")

    # Parse ellipses
    if "." in subscripts:
        used = subscripts.replace(".", "").replace(",", "").replace("->", "")
        ellipse_inds = "".join(gen_unused_symbols(used, max(len(x.shape) for x in operands)))
        longest = 0

        # Do we have an output to account for?
        if "->" in subscripts:
            input_tmp, output_sub = subscripts.split("->")
            split_subscripts = input_tmp.split(",")
            out_sub = True
        else:
            split_subscripts = subscripts.split(",")
            out_sub = False

        for num, sub in enumerate(split_subscripts):
            if "." in sub:
                if (sub.count(".") != 3) or (sub.count("...") != 1):
                    raise ValueError("Invalid Ellipses.")

                # Take into account numerical values
                if operands[num].shape == ():
                    ellipse_count = 0
                else:
                    ellipse_count = max(len(operands[num].shape), 1) - (len(sub) - 3)

                if ellipse_count > longest:
                    longest = ellipse_count

                if ellipse_count < 0:
                    raise ValueError("Ellipses lengths do not match.")
                elif ellipse_count == 0:
                    split_subscripts[num] = sub.replace("...", "")
                else:
                    split_subscripts[num] = sub.replace("...", ellipse_inds[-ellipse_count:])

        subscripts = ",".join(split_subscripts)

        # Figure out output ellipses
        if longest == 0:
            out_ellipse = ""
        else:
            out_ellipse = ellipse_inds[-longest:]

        if out_sub:
            subscripts += "->" + output_sub.replace("...", out_ellipse)
        else:
            # Special care for outputless ellipses
            output_subscript = find_output_str(subscripts)
            normal_inds = "".join(sorted(set(output_subscript) - set(out_ellipse)))

            subscripts += "->" + out_ellipse + normal_inds

    # Build output string if does not exist
    if "->" in subscripts:
        input_subscripts, output_subscript = subscripts.split("->")
    else:
        input_subscripts, output_subscript = subscripts, find_output_str(subscripts)

    # Make sure output subscripts are in the input
    for char in output_subscript:
        if char not in input_subscripts:
            raise ValueError("Output character '{}' did not appear in the input".format(char))

    # Make sure number operands is equivalent to the number of terms
    if len(input_subscripts.split(",")) != len(operands):
        raise ValueError("Number of einsum subscripts must be equal to the " "number of operands.")

    return input_subscripts, output_subscript, operands
def parse_einsum_input ( operands : Any ) -> Tuple [ str , str , List [ ArrayType ] ] : if len ( operands ) == 0 : raise ValueError ( "No input operands" ) if isinstance ( operands [ 0 ] , str ) : subscripts = operands [ 0 ] . replace ( " " , "" ) operands = [ possibly_convert_to_numpy ( x ) for x in operands [ 1 : ] ] else : subscripts , operands = convert_interleaved_input ( operands ) # Check for proper "->" if ( "-" in subscripts ) or ( ">" in subscripts ) : invalid = ( subscripts . count ( "-" ) > 1 ) or ( subscripts . count ( ">" ) > 1 ) if invalid or ( subscripts . count ( "->" ) != 1 ) : raise ValueError ( "Subscripts can only contain one '->'." ) # Parse ellipses if "." in subscripts : used = subscripts . replace ( "." , "" ) . replace ( "," , "" ) . replace ( "->" , "" ) ellipse_inds = "" . join ( gen_unused_symbols ( used , max ( len ( x . shape ) for x in operands ) ) ) longest = 0 # Do we have an output to account for? if "->" in subscripts : input_tmp , output_sub = subscripts . split ( "->" ) split_subscripts = input_tmp . split ( "," ) out_sub = True else : split_subscripts = subscripts . split ( "," ) out_sub = False for num , sub in enumerate ( split_subscripts ) : if "." in sub : if ( sub . count ( "." ) != 3 ) or ( sub . count ( "..." ) != 1 ) : raise ValueError ( "Invalid Ellipses." ) # Take into account numerical values if operands [ num ] . shape == ( ) : ellipse_count = 0 else : ellipse_count = max ( len ( operands [ num ] . shape ) , 1 ) - ( len ( sub ) - 3 ) if ellipse_count > longest : longest = ellipse_count if ellipse_count < 0 : raise ValueError ( "Ellipses lengths do not match." ) elif ellipse_count == 0 : split_subscripts [ num ] = sub . replace ( "..." , "" ) else : split_subscripts [ num ] = sub . replace ( "..." , ellipse_inds [ - ellipse_count : ] ) subscripts = "," . join ( split_subscripts ) # Figure out output ellipses if longest == 0 : out_ellipse = "" else : out_ellipse = ellipse_inds [ - longest : ] if out_sub : subscripts += "->" + output_sub . replace ( "..." , out_ellipse ) else : # Special care for outputless ellipses output_subscript = find_output_str ( subscripts ) normal_inds = "" . join ( sorted ( set ( output_subscript ) - set ( out_ellipse ) ) ) subscripts += "->" + out_ellipse + normal_inds # Build output string if does not exist if "->" in subscripts : input_subscripts , output_subscript = subscripts . split ( "->" ) else : input_subscripts , output_subscript = subscripts , find_output_str ( subscripts ) # Make sure output subscripts are in the input for char in output_subscript : if char not in input_subscripts : raise ValueError ( "Output character '{}' did not appear in the input" . format ( char ) ) # Make sure number operands is equivalent to the number of terms if len ( input_subscripts . split ( "," ) ) != len ( operands ) : raise ValueError ( "Number of einsum subscripts must be equal to the " "number of operands." ) return input_subscripts , output_subscript , operands