# Path: blaspy/helpers.py
# def get_matrix_dimensions(name, matrix):
#     """
#     Return the number of rows and number of columns in a matrix.
# 
#     Args:
#         name:      string to print as the vector's name if an error occurs
#         vector:    numpy 2D ndarray or matrix representing the matrix
# 
#     Returns:
#         A tuple of two elements where each element is described in order below:
# 
#         - number of rows in matrix
#         - number of columns in matrix
# 
#     Raises:
#         TypeError: if matrix is not a 2D NumPy ndarray or matrix
#     """
# 
#     try:
#         rows, cols = matrix.shape
# 
#         return rows, cols
# 
#     except (AttributeError, TypeError):
#         raise_not_2d_numpy(name)
# 
# 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 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 convert_trans(trans):
#     if trans == 'n' or trans == 'N':
#         return NO_TRANS
#     elif trans == 't' or trans == 'T':
#         return TRANS
#     else:
#         raise_invalid_parameter('trans', ('n', 'N', 't', 'T'), trans)
# 
# 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'))
# 
# ROW_MAJOR = 101
# 
# TRANS = 112


from ..helpers import (get_matrix_dimensions, create_zero_matrix, check_equal_sizes, convert_trans,
                       get_cblas_info, ROW_MAJOR, TRANS)
from ctypes import c_int, POINTER
                        < default is 'n' >
        trans_b:    'n'  if the operation is to proceed as if A is not transposed
                    't'  if the operation is to proceed as if b is transposed
                        < default is 'n' >
        alpha:      scalar alpha
                        < default is 1.0 >
        beta:       scalar beta
                        < default is 1.0 >
        lda:        leading dimension of A (must be >= # of cols in A)
                        < default is the number of columns in A >
        ldb:        leading dimension of B (must be >= # of cols in B)
                        < default is the number of columns in B >
        ldc:        leading dimension of C (must be >= # of cols in C)
                        < default is the number of columns in C >

    Returns:
        Matrix C (which is also overwritten)

    Raises:
        ValueError: if any of the following conditions occur:
                    - A, B, or C is not a 2D NumPy ndarray or NumPy matrix
                    - A, B, and C do not have the same dtype or that dtype is not supported
                    - the dimensions of A, B, and C do not conform
                    - either 'trans_a' or 'trans_b' is not equal to one of the following: 'n', 'N', 't', 'T'
    """

    # convert to appropriate CBLAS value
    cblas_trans_a = convert_trans(trans_a)
    cblas_trans_b = convert_trans(trans_b)
    transpose_a = cblas_trans_a == TRANS

# Path: blaspy/helpers.py
# def get_matrix_dimensions(name, matrix):
#     """
#     Return the number of rows and number of columns in a matrix.
# 
#     Args:
#         name:      string to print as the vector's name if an error occurs
#         vector:    numpy 2D ndarray or matrix representing the matrix
# 
#     Returns:
#         A tuple of two elements where each element is described in order below:
# 
#         - number of rows in matrix
#         - number of columns in matrix
# 
#     Raises:
#         TypeError: if matrix is not a 2D NumPy ndarray or matrix
#     """
# 
#     try:
#         rows, cols = matrix.shape
# 
#         return rows, cols
# 
#     except (AttributeError, TypeError):
#         raise_not_2d_numpy(name)
# 
# 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 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 convert_trans(trans):
#     if trans == 'n' or trans == 'N':
#         return NO_TRANS
#     elif trans == 't' or trans == 'T':
#         return TRANS
#     else:
#         raise_invalid_parameter('trans', ('n', 'N', 't', 'T'), trans)
# 
# 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'))
# 
# ROW_MAJOR = 101
# 
# TRANS = 112


# Path: blaspy/level_3/gemm.py
from ..helpers import (get_matrix_dimensions, create_zero_matrix, check_equal_sizes, convert_trans,
                       get_cblas_info, ROW_MAJOR, TRANS)
from ctypes import c_int, POINTER

                        < default is 'n' >
        trans_b:    'n'  if the operation is to proceed as if A is not transposed
                    't'  if the operation is to proceed as if b is transposed
                        < default is 'n' >
        alpha:      scalar alpha
                        < default is 1.0 >
        beta:       scalar beta
                        < default is 1.0 >
        lda:        leading dimension of A (must be >= # of cols in A)
                        < default is the number of columns in A >
        ldb:        leading dimension of B (must be >= # of cols in B)
                        < default is the number of columns in B >
        ldc:        leading dimension of C (must be >= # of cols in C)
                        < default is the number of columns in C >

    Returns:
        Matrix C (which is also overwritten)

    Raises:
        ValueError: if any of the following conditions occur:
                    - A, B, or C is not a 2D NumPy ndarray or NumPy matrix
                    - A, B, and C do not have the same dtype or that dtype is not supported
                    - the dimensions of A, B, and C do not conform
                    - either 'trans_a' or 'trans_b' is not equal to one of the following: 'n', 'N', 't', 'T'
    """

    # convert to appropriate CBLAS value
    cblas_trans_a = convert_trans(trans_a)
    cblas_trans_b = convert_trans(trans_b)
    transpose_a = cblas_trans_a == TRANS

    transpose_b = cblas_trans_b == TRANS