# Path: blaspy/helpers.py
# def get_vector_dimensions(name, vector, stride):
#     """
#     Return the number of rows, number of columns, and length of a vector taking into account
#     the stride of the vector.
# 
#     Args:
#         name:      string to print as the vector's name if an error occurs
#         vector:    numpy 2D ndarray or matrix representing a vector
#         stride:    stride of the vector (increment for the elements of the vector)
# 
#     Returns:
#         A tuple of three elements where each element is described in order below:
# 
#         - number of rows in vector
#         - number of columns in vector
#         - length of vector after accounting for stride
# 
#     Raises:
#         TypeError: if vector is not a vector represented by a 2D NumPy ndarray or matrix
#     """
# 
#     try:
#         rows, cols = vector.shape
# 
#         if not (rows == 1 or cols == 1):
#             raise_not_vector(name, rows, cols)
# 
#         length = max(rows, cols)
#         if stride > 1:
#             length = (length / stride) + (length % stride > 0)
# 
#         return rows, cols, length
# 
#     except (AttributeError, TypeError):
#         raise_not_2d_numpy(name)
# 
# def get_cblas_info(calling_func, dtypes):
#     """
#     Return the appropriate CBLAS subroutine and ctype data type based on the calling function and
#     dtypes of args.
# 
#     Args:
#         calling_func:    a string representation of the calling function
#         dtypes:          a tuple of the dtypes of all of the matrices or vectors passed into the
#                          calling function
# 
#     Returns:
#         A tuple of two elements where each element is described in order below:
# 
#         - appropriate CBLAS function
#         - appropriate ctypes data type
# 
#     Raises:
#         ValueError: if all matrices and/or vectors do not have the same dtype
#     """
# 
#     if all(dtype == 'float64' for dtype in dtypes):
#         return FUNC_DICT[calling_func][0], c_double
# 
#     elif all(dtype == 'float32' for dtype in dtypes):
#         return FUNC_DICT[calling_func][1], c_float
# 
#     else:
#         raise_invalid_dtypes(('float64', 'float32'))


from ..helpers import get_vector_dimensions, get_cblas_info
from ctypes import c_int, POINTER


def amax(x, inc_x=1):
    """
    Find and return the index of the element which has the maximum absolute value in the vector x.
    If the maximum absolute value is shared by more than one element, then the element whose index
    is lowest is chosen.

    Args:
        x:              2D NumPy matrix or ndarray representing vector x

        --optional arguments--

        inc_x:          stride of x (increment for the elements of x)
                            < default is 1 >

    Returns:
        The index of the element which has the maximum absolute value in the vector x.

    Raises:
        ValueError: if any of the following conditions occur:
                        - x is not a 2D NumPy matrix or ndarray
                        - x has a dtype that is not supported
                        - x is not a vector
    """

    # get the dimensions of the parameters
    m_x, n_x, x_length = get_vector_dimensions('x', x, inc_x)

    # determine which CBLAS subroutine to call and which ctypes data type to use

# Path: blaspy/helpers.py
# def get_vector_dimensions(name, vector, stride):
#     """
#     Return the number of rows, number of columns, and length of a vector taking into account
#     the stride of the vector.
# 
#     Args:
#         name:      string to print as the vector's name if an error occurs
#         vector:    numpy 2D ndarray or matrix representing a vector
#         stride:    stride of the vector (increment for the elements of the vector)
# 
#     Returns:
#         A tuple of three elements where each element is described in order below:
# 
#         - number of rows in vector
#         - number of columns in vector
#         - length of vector after accounting for stride
# 
#     Raises:
#         TypeError: if vector is not a vector represented by a 2D NumPy ndarray or matrix
#     """
# 
#     try:
#         rows, cols = vector.shape
# 
#         if not (rows == 1 or cols == 1):
#             raise_not_vector(name, rows, cols)
# 
#         length = max(rows, cols)
#         if stride > 1:
#             length = (length / stride) + (length % stride > 0)
# 
#         return rows, cols, length
# 
#     except (AttributeError, TypeError):
#         raise_not_2d_numpy(name)
# 
# def get_cblas_info(calling_func, dtypes):
#     """
#     Return the appropriate CBLAS subroutine and ctype data type based on the calling function and
#     dtypes of args.
# 
#     Args:
#         calling_func:    a string representation of the calling function
#         dtypes:          a tuple of the dtypes of all of the matrices or vectors passed into the
#                          calling function
# 
#     Returns:
#         A tuple of two elements where each element is described in order below:
# 
#         - appropriate CBLAS function
#         - appropriate ctypes data type
# 
#     Raises:
#         ValueError: if all matrices and/or vectors do not have the same dtype
#     """
# 
#     if all(dtype == 'float64' for dtype in dtypes):
#         return FUNC_DICT[calling_func][0], c_double
# 
#     elif all(dtype == 'float32' for dtype in dtypes):
#         return FUNC_DICT[calling_func][1], c_float
# 
#     else:
#         raise_invalid_dtypes(('float64', 'float32'))


# Path: blaspy/level_1/amax.py
from ..helpers import get_vector_dimensions, get_cblas_info
from ctypes import c_int, POINTER



def amax(x, inc_x=1):
    """
    Find and return the index of the element which has the maximum absolute value in the vector x.
    If the maximum absolute value is shared by more than one element, then the element whose index
    is lowest is chosen.

    Args:
        x:              2D NumPy matrix or ndarray representing vector x

        --optional arguments--

        inc_x:          stride of x (increment for the elements of x)
                            < default is 1 >

    Returns:
        The index of the element which has the maximum absolute value in the vector x.

    Raises:
        ValueError: if any of the following conditions occur:
                        - x is not a 2D NumPy matrix or ndarray
                        - x has a dtype that is not supported
                        - x is not a vector
    """

    # get the dimensions of the parameters
    m_x, n_x, x_length = get_vector_dimensions('x', x, inc_x)

    # determine which CBLAS subroutine to call and which ctypes data type to use

    cblas_func, ctype_dtype = get_cblas_info('amax', (x.dtype,))