# 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_square_matrix_dimension(name, matrix):
#     """
#     Return the dimension of a square matrix.
# 
#     Args:
#         name:      string to print as the matrix's name if an error occurs
#         vector:    numpy 2D ndarray or matrix representing a square matrix
# 
#     Returns:
#         An int representing both the number of rows and number of columns in matrix.
# 
#     Raises:
#         TypeError:  if matrix is not a 2D NumPy ndarray or matrix
#         ValueError: if matrix is not square
#     """
# 
#     try:
#         rows, cols = matrix.shape
# 
#         if rows != cols:
#             raise_not_square(name, rows, cols)
# 
#         return rows
# 
#     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'))
# 
# def check_equal_sizes(name_1, size_1, name_2, size_2):
#     """
#     Check that size_1 and size_2 are equal.
# 
#     Args:
#         name_1:    string to print as the name of the first element
#         size_1:    size of the first element
#         name_2:    string to print as the name of the second element
#         size_2:    size of the second element
# 
#     Raises:
#         ValueError: if size_1 != size_2
#     """
# 
#     if size_1 != size_2:
#         raise_size_mismatch(name_1, size_1, name_2, size_2)
# 
# def create_zero_matrix(rows, cols, dtype, matrix_type):
#     """
#     Create and return a zero matrix with the given number of rows and columns, and of the
#     appropriate dtype and matrix type.
# 
#     Args:
#         rows:         number of rows in the new matrix
#         cols:         number of columns in the new matrix
#         dtype:        NumPy dtype for the elements of the new matrix
#         matrix_type:  either NumPy ndarray or matrix; the new matrix will be of the same type
# 
#     Returns:
#         A new NumPy ndarray or matrix filled with zeros of specified dimensions and dtype.
#     """
# 
#     new_matrix = zeros((rows, cols), dtype=dtype)
# 
#     if matrix_type == np_matrix:
#         return asmatrix(new_matrix)
#     else:
#         return new_matrix
# 
# def convert_uplo(uplo):
#     if uplo == 'u' or uplo == 'U':
#         return UPPER
#     elif uplo == 'l' or uplo == 'L':
#         return LOWER
#     else:
#         raise_invalid_parameter('uplo', ('u', 'U', 'l', 'L'), uplo)
# 
# ROW_MAJOR = 101


from ..helpers import (get_vector_dimensions, get_square_matrix_dimension, get_cblas_info,
                       check_equal_sizes, create_zero_matrix, convert_uplo, ROW_MAJOR)
from ctypes import c_int, POINTER
        --optional arguments--

        A:        2D NumPy matrix or ndarray representing matrix A
                      < default is the zero matrix >
        uplo:     'u'  if the upper triangle of A is to be used
                  'l'  if the lower triangle of A is to be used
                      < default is 'u' >
        alpha:    scalar alpha
                      < default is 1.0 >
        lda:      leading dimension of A (must be >= # of cols in A)
                      < default is the number of columns in A >
        inc_x:    stride of x (increment for the elements of x)
                      < default is 1 >
        inc_y:    stride of y (increment for the elements of y)
                      < default is 1 >

    Returns:
        Matrix A (which is also overwritten)

    Raises:
        ValueError: if any of the following conditions occur:
                    - A, x, or y is not a 2D NumPy ndarray or NumPy matrix
                    - A, x, and y do not have the same dtype or that dtype is not supported
                    - x or y is not a vector
                    - the effective length of either x or y does not conform to the dimensions of A
                    - uplo is not equal to one of the following: 'u', 'U', 'l', 'L'
    """

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

# 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_square_matrix_dimension(name, matrix):
#     """
#     Return the dimension of a square matrix.
# 
#     Args:
#         name:      string to print as the matrix's name if an error occurs
#         vector:    numpy 2D ndarray or matrix representing a square matrix
# 
#     Returns:
#         An int representing both the number of rows and number of columns in matrix.
# 
#     Raises:
#         TypeError:  if matrix is not a 2D NumPy ndarray or matrix
#         ValueError: if matrix is not square
#     """
# 
#     try:
#         rows, cols = matrix.shape
# 
#         if rows != cols:
#             raise_not_square(name, rows, cols)
# 
#         return rows
# 
#     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'))
# 
# def check_equal_sizes(name_1, size_1, name_2, size_2):
#     """
#     Check that size_1 and size_2 are equal.
# 
#     Args:
#         name_1:    string to print as the name of the first element
#         size_1:    size of the first element
#         name_2:    string to print as the name of the second element
#         size_2:    size of the second element
# 
#     Raises:
#         ValueError: if size_1 != size_2
#     """
# 
#     if size_1 != size_2:
#         raise_size_mismatch(name_1, size_1, name_2, size_2)
# 
# def create_zero_matrix(rows, cols, dtype, matrix_type):
#     """
#     Create and return a zero matrix with the given number of rows and columns, and of the
#     appropriate dtype and matrix type.
# 
#     Args:
#         rows:         number of rows in the new matrix
#         cols:         number of columns in the new matrix
#         dtype:        NumPy dtype for the elements of the new matrix
#         matrix_type:  either NumPy ndarray or matrix; the new matrix will be of the same type
# 
#     Returns:
#         A new NumPy ndarray or matrix filled with zeros of specified dimensions and dtype.
#     """
# 
#     new_matrix = zeros((rows, cols), dtype=dtype)
# 
#     if matrix_type == np_matrix:
#         return asmatrix(new_matrix)
#     else:
#         return new_matrix
# 
# def convert_uplo(uplo):
#     if uplo == 'u' or uplo == 'U':
#         return UPPER
#     elif uplo == 'l' or uplo == 'L':
#         return LOWER
#     else:
#         raise_invalid_parameter('uplo', ('u', 'U', 'l', 'L'), uplo)
# 
# ROW_MAJOR = 101


# Path: blaspy/level_2/syr2.py
from ..helpers import (get_vector_dimensions, get_square_matrix_dimension, get_cblas_info,
                       check_equal_sizes, create_zero_matrix, convert_uplo, ROW_MAJOR)
from ctypes import c_int, POINTER

        --optional arguments--

        A:        2D NumPy matrix or ndarray representing matrix A
                      < default is the zero matrix >
        uplo:     'u'  if the upper triangle of A is to be used
                  'l'  if the lower triangle of A is to be used
                      < default is 'u' >
        alpha:    scalar alpha
                      < default is 1.0 >
        lda:      leading dimension of A (must be >= # of cols in A)
                      < default is the number of columns in A >
        inc_x:    stride of x (increment for the elements of x)
                      < default is 1 >
        inc_y:    stride of y (increment for the elements of y)
                      < default is 1 >

    Returns:
        Matrix A (which is also overwritten)

    Raises:
        ValueError: if any of the following conditions occur:
                    - A, x, or y is not a 2D NumPy ndarray or NumPy matrix
                    - A, x, and y do not have the same dtype or that dtype is not supported
                    - x or y is not a vector
                    - the effective length of either x or y does not conform to the dimensions of A
                    - uplo is not equal to one of the following: 'u', 'U', 'l', 'L'
    """

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

    m_y, n_y, y_length = get_vector_dimensions('y', y, inc_y)